5962. 连接两字母单词得到的最长回文串
给你一个字符串数组 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 <= 105
- words[i].length == 2
- words[i] 仅包含小写英文字母。
解题思路:
贪心
此题分为两种情况可构造回文串,“cl"和"lc”, 或者只有一个的"xx",可模拟一个二维数组或者一维数组来判断cl 和lc的匹配个数,最后再计算是否有奇数个xx的个数。
代码:
一维数组
int longestPalindrome(char ** words, int wordsSize){
int a[1000] = {0};
int i;
int len = 0;
for(i = 0; i < wordsSize; i++)
{
if(a[(words[i][0] - 'a') + (words[i][1] - 'a')*26] != 0)
{
len += 4;
a[(words[i][0] - 'a') + (words[i][1] - 'a')*26]--;
}
else
{
a[26*(words[i][0] - 'a') + (words[i][1] - 'a')]++;
}
}
for(i = 0; i < wordsSize; i++)
{
if(words[i][0] == words[i][1] && a[(words[i][0] - 'a')+(words[i][1] - 'a')*26])
{
len += 2;
break;
}
}
return len;
}
二维数组
class Solution {
public:
int longestPalindrome(vector<string>& words) {
int a[26][26] = {0};
int len = 0;
for(int i = 0; i < words.size(); i++)
{
int b = words[i][0] - 'a', c = words[i][1] - 'a';
if(a[c][b])
{
len +=4;
a[c][b]--;
}
else
a[b][c]++;
}
for(int i = 0; i < words.size(); i++)
{
int b = words[i][0] - 'a', c = words[i][1] - 'a';
if(a[c][b] && words[i][0] == words[i][1])
{
len +=2;
break;
}
}
return len;
}
};
时间复杂度: O(n)
空间复杂度: O(1)