题目描述
给你一个字符串数组 words
。words
中每个元素都是一个包含两个小写英文字母的单词。请你从 words
中选择一些元素并按任意顺序连接它们,并得到一个尽可能长的回文串 。每个元素至多只能使用一次。请你返回你能得到的最长回文串的长度 。如果没办法得到任何一个回文串,请你返回 0
。
说明:回文串
指的是从前往后和从后往前读一样的字符串。
示例 1:
输入:words = [“lc”, “cl”, “gg”]
输出:6
解释:一个最长的回文串为 “lc” + “gg” + “cl” = “lcggcl” ,长度为 6 。”clgglc” 是另一个可以得到的最长回文串。
示例 2:
输入:words = [“ab”, “ty”, “yt”, “lc”, “cl”, “ab”]
输出:8
解释:最长回文串是 “ty” + “lc” + “cl” + “yt” = “tylcclyt” ,长度为 8 。”lcyttycl” 是另一个可以得到的最长回文串。
示例 3:
输入:words = [“cc”, “ll”, “xx”]
输出:2
解释:最长回文串是 “cc” ,长度为 2 。”ll” 是另一个可以得到的最长回文串。”xx” 也是。
提示:
1 <= words.length <= 10^5
words[i].length == 2
words[i]
仅包含小写英文字母。
思路分析
- 统计单词出现次数:使用哈希表记录每个单词的出现次数。
- 处理互为反转的单词对:对于每个单词,检查其反转是否存在。若存在,取两者出现次数的较小值,每对贡献
4
个字符(每个单词长度为2
)。 - 处理对称单词:对于两个字符相同的单词(如
"aa"
),可以成对使用(贡献4
个字符),若有剩余且未使用中间点,可单独作为中间对称点(贡献2
个字符)。 - 避免重复处理:使用集合记录已处理的单词,确保每对单词只处理一次。
1 | public int longestPalindrome(String[] words) { |
复杂度分析
- 时间复杂度:
O(n)
,遍历words
数组并构建哈希表wordCount
,时间复杂度为O(n)
,遍历哈希表的键集合,假设不同的单词数量为m
,每个单词的处理包括生成反转字符串、哈希表查询等操作。由于每个单词长度为2
,生成反转字符串和哈希表操作均为O(1)
,总时间复杂度为O(m)
。最坏情况下,所有单词均不同(即m = n
),时间复杂度为O(n)
。其中n
是数组长度。 - 空间复杂度:
O(n)
,wordCount
存储所有单词及其频率,占用O(m)
空间。processed
集合存储已处理的单词,需要O(m)
空间。总体空间复杂度:O(m)
,即O(n)
(m
最大为n
)。