Leetcode 刷题 - 266 - Palindrome Permutation

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。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值