检查字符串以查看它是否是任何排列的回文

时间:2016-02-13 07:35:20

标签: python time-complexity

我已经创建了一个成功完成此功能的功能(我很确定),但我担心其部分效率。我有两个嵌套的for循环,我认为这个算法是围绕O(n ^ 2)的最坏情况。有什么方法可以改善这个吗?

def palindrome(string):
    s = [c.replace(' ', '') for c in string]
    merged = "".join(s)
    srt = sorted(merged)
    dic = {}
    singles = 0

    for i in srt:
        if i not in dic:
            dic[i] = 1
        else:
            # Worried about this second loop having to run for every i in srt
            for key, value in dic.items():
                if key == i:
                    dic[key] = 2 
    for key, value in dic.items():
        if value == 1:
            singles += 1
    if singles > 1:
        return False
    else:
        return True

3 个答案:

答案 0 :(得分:1)

因为它测试字符串中字母的任何排列是否可以是回文。

我建议:

from collections import Counter

def palindrome(string):
    s = string.replace(' ', '')
    return not sum(v % 2 == 1 for k,v in Counter(string)) > 1

对奇数字符出现次数总和的检查不大于一。

答案 1 :(得分:1)

你需要的是找出最多只有一个"单个"信(和其他人配对)。因此,我们用collections.Counter计算字母数,并确保只有0或1个具有奇数:

from collections import Counter


def has_palindrome(string):
    return sum(v % 2 for v in Counter(string).values()) <= 1

print(has_palindrome('abcabcc'))  # True
print(has_palindrome('abc'))  # False

答案 2 :(得分:0)

如果出现三个特定字符,则以上代码将失败。尝试abcabccddd

稍作修改即可解决该问题:

def checkPalindromPermutation(word):
    values = collections.Counter(word).values()
    if sum((v % 2) for v in values) > 1 or any(v > 2 for v in values):
        return False
    return True