大概是脑子开窍了,想到了一个O(n)的算法
解题思路:首先你得知道ASCII码,我用的是C++,C++字符编码是按照ASCII码来的,java是Unicode,不过一般字符是连续编码的,所以用其它语言的同学注意一下。
使用一个标志数组,大小是52,分别对应的是26个小写和大写字母。那么怎么通过字符找到对应的数组位置呢?首先判断一下是小写字母还是大写字母;
小写字母:index = letter - 'a'
大写字母:index = letter - 'A' + 26
找到字母,就将其对应数组位置的存储值加一
处理完字符串之后遍历数组,如果改位置存储值为空,continue;如果是偶数,length += array[i];如果是大于二的奇数,length = length + array[i] - 1;
循环结束后,最后看一下数组中是否存在奇数值,有length +=1;最后返回length(记住length需要初始化)
代码:
class Solution {
public:
/*
* @param s: a string which consists of lowercase or uppercase letters
* @return: the length of the longest palindromes that can be built
*/
int longestPalindrome(string s) {
// write your code here
if(s.empty()) return 0;
if(1 == s.size()) return 1;
int length = 0;
int letterArray[52];
for(int i = 0; i < 52; ++i) letterArray[i] = 0;
for(int i = 0, j = 0; i < s.size(); ++i)
{
if(s[i] >= 'a' && s[i] <= 'z')
{
j = s[i] - 'a';
}
else
{
j = s[i] - 'A' + 26;
}
++letterArray[j];
}
bool flag = false;
for(int i = 0; i < 52; ++i)
{
if(0 == letterArray[i]);
else if( 0 == letterArray[i] % 2) length += letterArray[i];
else
{
if(letterArray[i] > 2)
{
length += (letterArray[i] - 1);
}
flag = true;
}
}
if(flag) ++length;
return length;
}
};
PS:提交了几次,都是细节问题。一个是ASCII码表中大写字母的编码在前面,小写的在后面,中间还隔了几个值;还有就是一开始没有理清楚length怎么加,分哪几种情况,奇数的一开始只加了一个1(其实:奇数 = 偶数 + 1)