题目:
思路:
经过分析可以得到,在回文串中,如果是偶数长度的回文串,则每个字符出现的次数都是偶数,如果是奇数字符串,则除了中心字符出现次数是奇数,其他字符出现次数都是偶数。
依据上述思路,有下述伪代码:
1.首先利用字典计数每个字符出现的次数;
2.然后遍历字典的value,如果是偶数次数,就算入回文串的长度temp,如果是奇数次数(odd),对temp 执行:temp+=(odd//2)*2
3.最后判断temp的长度是否和原字符串相等,如果相等(即原字符串中不存在出现次数为奇数的字符),则temp的值即为所求;否则返回temp + 1(原字符串中存在出现次数为奇数的字符,构成的回文串是奇数回文串)
代码如下:
class Solution:
def longestPalindrome(self, s):
#对字符串进行计数,统计每个字符出现的次数
#建立字典进行计数
temp = collections.Counter(s)
count_temp = 0
#遍历字典
for i in temp.values():
if i % 2 == 0:
count_temp += i
else:
if i > 1:
count_temp += (i//2)*2
if count_temp < len(s):
count_temp += 1
return count_temp
代码优化:
对奇数和偶数次数的字符归为一类,每次都是对回文串的长度增加temp+=(当前字符出现的次数//2)*2;
代码如下:
class Solution:
def longestPalindrome(self, s):
#对字符串进行计数,统计每个字符出现的次数
#建立字典进行计数
temp = collections.Counter(s)
# print(temp)
count_temp = 0
for i in temp.values():
count_temp += (i//2)*2
if count_temp < len(s):
count_temp += 1
# print(count_temp)
return count_temp
思路二:
把出现奇数和偶数次数的字符归为一类,因为无论是奇数还是偶数,每次回文串的长度都应该新增(当前字符出现的次数v)(v// 2)*2,如果遇到出现奇数次数的字符,则只在第一次遇到奇数次数时对回文串的长度进行加1,后面不再进行加1。
官方题解代码:
class Solution:
def longestPalindrome(self, s):
ans = 0
count = collections.Counter(s)
for v in count.values():
ans += v // 2 * 2
if ans % 2 == 0 and v % 2 == 1:
ans += 1
return ans