Description
Note
Example 1
Solution 1(C++)
class Solution {
public:
int longestPalindrome(string s) {
unordered_map<char,int> nums;
for(char c:s){
nums[c]++;
}
int lenout=0;
for(auto a:nums){
if(a.second%2==0){
lenout+=a.second;
}
else {
lenout+= lenout%2?a.second-1:a.second;
}
}
return lenout;
}
};
Solution 2(C++)
class Solution {
public:
int longestPalindrome(string s) {
vector<int> m(256, 0);
for (auto& c : s) m[c-'0']++; //这里原答案是'\\0',应该为'0'
int result = 0;
for (auto& i : m) result += i%2 ? (result%2 ? i-1 : i) : i;
return result;
}
};
算法分析
这个题目要求找到最大的回文字符串的长度。其实挺简单。我最开始的错误想法是:由于要求回文字符串,所以字符串长度要么为偶数,要么为奇数。而偶数的情况一定是其中所有字符出现的次数都为偶数;而奇数的情况一定是只有一个字符出现次数为奇数,其他字符出现次数都为偶数。
于是,我就想,计算string中所有字符串出现的次数,如果为偶数,全部加起来,如果为奇数,那么只求出最大的奇数,加起来,就是最终答案了。
但是,这是错误的,因为我对题目意思没有理解到位。其实,不是说,要么一定将一个字符全部使用,要么,一个都不使用。其意思就是。“aaabbb”按照我之前的做法,组成的最长回文字符串就是“aaa”或“bbb”,其实正确答案应该是“abbba”。a虽然出现了三次,但是,我们不一定都要把三个a全都用到。
所以正确的做法就是,字符出现次数为偶数都加起来,遇到一个奇数次,就都加起来,如果此后还遇到奇数次的字符,那么就-1,只取最大偶数个,这样组成的回文字符串最大。
程序分析
我使用了unordered_map,其实也可以使用vector。但是要设定
vector<int> m(256, 0);
然后,通过这样的方法计算字符出现的次数:
for (auto& c : s)
m[c-'\\0']++;
此外,要注意解法二中注释部分。