题目: 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。在构造过程中,请注意区分大小写。比如 “Aa” 不能当做一个回文字符串。
注意:假设字符串的长度不会超过 1010。
示例:
输入:“abccccdd”
输出:7
解释:我们可以构造的最长的回文串是"dccaccd",它的长度是 7。
思想1: 正向思维,就是统计有多少个偶数字母加上1个奇数字母。这个题目和拼写单词题目都可以用数组来统计出现次数,不过这次有大小写字母之分,我们就需要设置数组长度为128,a和A的ASCII码的范围。
- 首先我们需要知道aaa这样的我们需要count+2而不是不加,因为它包含了2个a。
- 为了避免大于2的奇数没被加,我们采用算式:v/2*2来统计,v为偶数如4则:4/2*2=4,v为奇数,5则5/2*2=4只统计了偶数次数的,这样就解决了。
- 只能统计一个奇数,因为只需要一个多出来的做分隔符,我们碰到第一个奇数时把它就加上,以后既不能加了。我们可以判断当前的总数是否%2==0,当前的这个数是否%2==1,来判断是否加了奇数,一旦加了一个奇数第二个条件便会不能不满足。
根据上述思想写出代码:
代码1:
int longestPalindrome1(string s)
{
int a[128]={0};//a和A的ASII码
int num=0;
for(int i=0;i<s.size();i++)
{
a[s[i]]++;
}
for(int i=0;i<128;i++)
{
num=num+(a[i]/2*2);
if(a[i]%2==1&&num%2==0)//只加一次1
{
num++;
}
}
return num;
}
思想2: 反向思维,不难发现我们也可以统计奇数出现的次数,然后总数目-奇数次数+1即可。试一下哈希表。
代码2:
int longestPalindrome(string s)
{
unordered_map<char,int>hash;//定义哈希
int count=0;
int len=s.size();
for(int i=0;i<s.size();i++)
{
hash[s[i]]++;//记录次数
}
for(auto i:hash)//循环
{
if(i.second%2==1)//判断奇数
{
count++;
}
}
return count==0?len:len-count+1;
}
int main()
{
string s="abccccdd";
cout<<longestPalindrome(s);
}
加油哦!(●ˇ∀ˇ●)。