You are given an array of strings words
. Each element of words
consists of two lowercase English letters.
Create the longest possible palindrome by selecting some elements from words
and concatenating them in any order. Each element can be selected at most once.
Return the length of the longest palindrome that you can create. If it is impossible to create any palindrome, return 0
.
A palindrome is a string that reads the same forward and backward.
Example 1:
Input: words = ["lc","cl","gg"] Output: 6 Explanation: One longest palindrome is "lc" + "gg" + "cl" = "lcggcl", of length 6. Note that "clgglc" is another longest palindrome that can be created.
Example 2:
Input: words = ["ab","ty","yt","lc","cl","ab"] Output: 8 Explanation: One longest palindrome is "ty" + "lc" + "cl" + "yt" = "tylcclyt", of length 8. Note that "lcyttycl" is another longest palindrome that can be created.
Example 3:
Input: words = ["cc","ll","xx"] Output: 2 Explanation: One longest palindrome is "cc", of length 2. Note that "ll" is another longest palindrome that can be created, and so is "xx".
Constraints:
1 <= words.length <= 105
words[i].length == 2
words[i]
consists of lowercase English letters.This problem asks to find the length of the longest palindrome that can be created by concatenating strings from a given array, where each string has a length of 2. The solution leverages a greedy approach combined with hash map (or dictionary) for efficient counting.
Approach:
Counting Word Frequencies: We first count the occurrences of each two-letter word using a hash map (e.g., Counter
in Python, HashMap
in Java). This allows for quick lookups of word frequencies.
Processing Words: We iterate through the unique words in the hash map. We consider two cases:
Words with Identical Characters: If a word has identical characters (e.g., "aa", "bb"), we can use pairs of these words to form a palindrome. We add the number of such pairs multiplied by 4 to the total length (ans
). The remaining single word can be possibly used in the middle of the palindrome, so we store the count of remaining single words in x
.
Words with Different Characters: If a word has different characters (e.g., "ab", "ba"), we can create a palindrome if we find its reverse ("ba" for "ab"). We add the minimum of the counts of the word and its reverse, multiplied by 2, to ans
, as we need pairs of these words.
Handling the Middle Character: If x
(the count of remaining single words with identical characters) is greater than 0, we can add 2 to ans
, as we can place one of these words in the middle of the palindrome.
Time and Space Complexity:
Time Complexity: O(N), where N is the number of words. This is because we iterate through the words once to count frequencies and then iterate through the unique words (at most N unique words). The other operations within the loops are constant time.
Space Complexity: O(M), where M is the number of unique words. This is the space required to store the frequency counts in the hash map. In the worst case, M could be as large as N, but usually, it will be much smaller than N.
Code Explanation (Python):
from collections import Counter
class Solution:
def longestPalindrome(self, words: List[str]) -> int:
cnt = Counter(words) # Count word frequencies
ans = x = 0 # ans: total palindrome length, x: count of words with identical characters
for word, count in cnt.items():
if word[0] == word[1]: # Identical characters
x += count % 2 # count of remaining single words
ans += (count // 2) * 4 # Pairs of words
else: # Different characters
reverse_word = word[::-1] # Reverse the word
ans += min(count, cnt[reverse_word]) * 2 # Add pairs
ans += 2 if x > 0 else 0 # Add middle character if any
return ans
The Java, C++, and Go code follow a very similar structure and logic, just adapting the syntax and data structures of each language. They all achieve the same time and space complexity.