大概是脑子开窍了,想到了一个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)