给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。
在构造过程中,请注意区分大小写。比如 “Aa” 不能当做一个回文字符串。
注意:
假设字符串的长度不会超过 1010。
示例 1:
输入:
“abccccdd”
输出:
7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
首先这道题就是计算给出的字符串中字母的个数分类,如果全都是偶数那么毫无疑问给出的长度就是这个长度,否则我们可以先将奇数的字符数目取偶数,但是最后我们组成回文串的时候可以将一个字符放在中间,这样就可以将长度增加1,这里用的是count数组存放字符出现的次数,代码如下:直接使用长度为52的int型数组,计算下标时注意一下就ok了,直接撸出代码:
class Solution {
public int longestPalindrome(String s) {
//如果s为空或者字符串长度为0,那么返回零
if(s == null || s.length() == 0)
return 0;
//用于存放结果长度
int result = 0;
//构造一个数组用于存放所有出现的字符个数
int [] count = new int[52];
for (int i = 0; i < s.length(); i++) {
char tem = s.charAt(i);
//如果是大写的话,那么数组下标从零开始到25
if(Character.isUpperCase(tem)){
count[tem - 65] ++;
}
//如果是小写的话,数组下标从26开始到51,定义的数组大小刚刚好
else {
count[tem - 71]++;
}
}
boolean flag = false;
for (int i = 0; i < count.length; i++) {
int j = count[i];
if(j % 2 == 0){
result +=j;
}else {
//如果是奇数的话,取其偶数构成
result = result +(j/2)*2;
flag = true;
}
}
//如果有奇数比如有aaa,那么我们可以取出一个放入中间
return flag ? result +1 : result;
}
}
效率蛮高的
排名靠前的代码,区别就是将奇数转成偶数的,我是除2然后乘2,效率可能不是很高,这里直接-1,效率比较高
class Solution {
public int longestPalindrome(String s) {
int max = 'z' - 'A' + 1;
int[] mark = new int[max];
int maxLen = 0;
char[] s1 = s.toCharArray();
for (char aS1 : s1) {
mark[aS1 - 'A']++;
}
boolean flag = false;
for (int i = 0; i < max; i++) {
if (mark[i] != 0) {
if (mark[i] % 2 == 0) {
maxLen += mark[i];
} else {
if (mark[i] >= 1) {
flag = true;
maxLen += mark[i] - 1;
}
}
}
}
return flag ? maxLen + 1 : maxLen;
}
}