题目
给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。
回文串是指正反两个方向都一样的单词或词语。排列是指字母的重新排列。
回文串不一定是字典当中的单词。
思路
class Solution:
def canPermutePalindrome(self, s: str) -> bool:
ch_num = dict()
for ch in s:
ch_num[ch] = ch_num.get(ch, 0) + 1
length = len(s)
tmp = [num % 2 == 0 for num in ch_num.values()]
print(tmp)
if length % 2 == 0:
# 所有字符的数量都是偶数
return all(tmp)
else:
# 有且只要一个字符的数量为奇数
return (len(ch_num) - sum(tmp)) == 1
更好的办法应该用位操作来实现。
题目理解:如果是回文,只存在1个或者0个出现次数为奇数的数(字符串转换为数字ord(ch))。
flag = 0
- 如果字符串数量len(s)有偶数个,利用性质 flag ^ a ^a=flag的性质,遍历所有字符,最终flag = 0;
- 如果字符数量len(s)有奇数个,那么有且只有1个字符的数量ch为1个,1左移ord(ch)必定为2的次方。判断二进制中有且只有1位为1或者是2的n次方,方法是 flag & (flag - 1) == 0
class Solution:
def canPermutePalindrome(self, s: str) -> bool:
# 位运算
# a ^ a = 0
# a ^ 0 = a
flag = 0
for ch in s:
flag ^= 1 << ord(ch)
return flag & (flag - 1) == 0