题目:
给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。
在构造过程中,请注意区分大小写。比如 “Aa” 不能当做一个回文字符串。
注意:
假设字符串的长度不会超过 1010。
示例 1:
输入:
“abccccdd”
输出:
7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
我给出的解答:
int longestPalindrome(string s) {
sort(s.begin(), s.end());
auto z = s.cbegin();
auto a = s.cbegin();
int final = 0; bool odd = 0;
while (z!=s.cend())
{
int tem = 0;
while (z != s.cend() && *z == *a)
{
tem++;
z++;
}
if (!(tem % 2)) final += tem;
else {
final += tem - 1;
odd = 1;
}
a = z;
}
if (odd)return final + 1;
else return final;
}
运用sort()函数将字符串重排,双迭代器从头开始遍历相同的元素。若为偶数就直接加进去,若为奇数就-1加进去。
只要存在过奇数的字符,总可以找到一个数最大的放在中间也可以回文,故在最后判断是否存在过奇数。
有较好的空间复杂度,几乎为0,但有较差的时间复杂度。因为有sort函数。
值得注意的是sort函数的用法:sort(S.begin(),S.end())
官方解答:
思路完全一致,不过方法优美许多。
int longestPalindrome(string s) {
unordered_map<char, int> count;
int ans = 0;
for (char c : s)
++count[c];
for (auto p : count) {
int v = p.second;//取int
ans += v / 2 * 2;
if (v % 2 == 1 and ans % 2 == 0)//最长奇数加一并确保之前没加过奇数
++ans;
}
return ans;
}