Given a string, determine if a permutation of the string could form a palindrome.
For example,
"code"
-> False, "aab"
-> True, "carerac"
-> True.
根据题意,判断一个string是否仅需要调换一下字母的顺序就能得到回文字符串。线索是请考虑length是奇数和偶数情况下的不同。
class Solution(object):
def canPermutePalindrome(self, s):
"""
:type s: str
:rtype: bool
"""
d = {}
for i in s:
d[i] = d.get(i, 0) + 1
count = 0
for i in d.values():
if i % 2 != 0:
count += 1
if count > 1:
return False
return True
首先,考虑到字符的重复性,需要排除重复值。可以用能产生key-value的数据结构,Java中用Hashtable, Hashmap之类的,Python中可以使用字典dictionary。
d = {}
for i in s:
if d.keys().__contains__(i):
d[i] += 1
else:
d.keys().append(i)
d[i] = 1
如果字典中有的话,就value值+1,没有就生成一个,给值1。
然后创建完字典之后,就需要考虑是否能够得到回文。根据线索说的考虑奇偶性。
奇数情况下,假设能够回文,必须是中间有一个value值是1,或者奇数的字符,且仅有一个这样的字符。
偶数情况下,假设能够回文,必须是每一个字符的value值都是偶数。
所以对于一个字符串来说,我们统一只需要考虑,值的list中,奇数的个数有没有超过1个,超过了就不能够回文,返回False。否则就是回文字符串。
count = 0
for i in d.values():
if i % 2 != 0:
count += 1
if count > 1:
return False
return True
P.S. 一开始理解错题意,以为是对于字符串string仅仅改动一次,就得到回文字符串,得到以下代码,测试的test case并不多,也不知道是否bug free
def canPermutePalindrome(s):
"""
:type s: str
:rtype: bool
"""
d = {}
for i in s:
if d.keys().__contains__(i):
d[i] += 1
else:
d.keys().append(i)
d[i] = 1
#flag = True
count = 0
for i in d.values():
if i % 2 != 0:
count += 1
if count > 1:
return False
#flag = False
'''
misCound = 0
if flag:
for i in range(len(s)/2):
if s[i] != s[-1-i]:
misCound += 1
if misCound > 2:
return False
return True
else:
mid = len(s)/2
for i in range(len(s)/2):
if s[i] != s[-1-i]:
misCound += 1
if (s[mid] == s[i] or s[mid] == s[-1-i]) and misCound == 2:
return False
elif misCound > 2:
return False
return True
'''
return True
关键点就是在奇数偶数上。
奇数的时候要关注mid中间点的数字。情况1,一旦有对称位置字符不对应,就要去跟中间mid比较,如果有一样,就换一次。换一次之后继续,如果midMatch达到2次就是False。情况2,如果不相同,那就是说mid必然是单一的只能放在mid的字符,允许有两次的misMatch。
对于偶数,只有一个条件,就是允许有两次的misMatch。