解题思路:
这道题目主要是看清字符串中的字符顺序不是固定死的,可以随意组合的,跟从指定字符串中求最大回本字符串不一样,参考网上的结题思路比较有投机性,首先要理解回文字符串的组成,不理解就无法下手。
回文串分两种:一种是全部由出现偶数次的字符构成 如abba
一种是由出现偶数次的字符+出现奇数次的字符构成 如 abcba
第二种回文串只允许有一个出现奇数次的字符
我们可以发现第一种回文串的长度是:所有出现偶数次的字符的个数之和
第二种回文串的长度是:所有出现偶数次的字符的个数之和+1
这个1就是唯一的一个被允许出现在回文串中的字符
1 统计s字符串中所有字符的个数
2 遍历存储所有字符个数的数组:
若是某个字符出现的次数是偶数次,则直接加上它的个数
若是出现的次数是奇数次,则加上它的个数-1
这样做的目标是使得这个出现奇数次的字符变成出现偶数次
3 比较ret和字符串s的长度len
若是ret==len:表示该能构成的最长回文串全部都是由出现偶数次的字符构成的
若是ret!=len:表示最长回文串是由出现偶数次的字符+出现奇数次的字符构成的
则最长回文串的长度是ret+1(ret中存储的是全部出现偶数次字符的个数之和)
int longestPalindrome(char * s)
{
int len = strlen(s);
//开辟58个空间的原因是,字符串s中可以出现A~Z a~z//要能存储以上字符的ASCII码值,按照最大空间来算,z的ASCII码值是122
int arr[58] = { 0 };
z-'A' = 122-65 = 57
int i = 0;
for (i = 0; i < len; i++)
{
arr[s[i] - 'A']++;
}
int ret = 0;
for (i = 0; i < 58; i++)
{
ret += arr[i] - arr[i] % 2;
}
if (ret != len) //不相同说明字符串长度不是偶数,回文字符串长度还可以加1
{
ret += 1;
}
return ret;
}