Python HashTable实现比列表迭代更快?

时间:2018-05-15 12:30:20

标签: python python-3.x big-o

这是problem from HackerRank。我的实现如下所示通过了大部分测试,但对于失败的测试,它表明它花了太长时间。在查看其他提交后,我发现另一个用户的实现(信用到saikiran9194)几乎立即通过了所有测试。我真的很难理解为什么他的解决方案是最有效的。

我的实施:

m, n = map(int, input().strip().split(' '))
magazine = input().strip().split(' ')
ransom = input().strip().split(' ')
yesNo = "Yes"
for i in ransom:
    if(ransom.count(i) > magazine.count(i)):
        yesNo = "No"
print(yesNo)

更及时的实施

def ransom_note(magazine, ransom):
    rc = {} # dict of word: count of that word in the note
    for word in ransom:
        if word not in rc:
            rc[word] = 0
        rc[word] += 1

    for word in magazine:
        if word in rc:
            rc[word] -= 1
            if rc[word] == 0:
                del rc[word]
                if not rc:
                    return True
    return False

m, n = map(int, input().strip().split(' '))
magazine = input().strip().split(' ')
ransom = input().strip().split(' ')
answer = ransom_note(magazine, ransom)
if(answer):
    print("Yes")
else:
    print("No")

2 个答案:

答案 0 :(得分:1)

list.countdict.__getitem__rc[word])之间的区别。 list.countO(n),而dict.__getitem__O(1),正如您所提到的那样,是因为哈希。

来源:https://wiki.python.org/moin/TimeComplexity

答案 1 :(得分:1)

list.count具有线性复杂度,因此您的代码总体上具有二次复杂度,在循环的每次迭代中执行线性工作。首先将列表放在dict中,只需要O(1)来获取某个字母的计数。

您可以将这些列表包装到collections.Counter(未测试)中:

m, n = map(int, input().strip().split())
magazine = Counter(input().strip().split())
ransom = Counter(input().strip().split())
yesNo = "Yes"
for i in ransom:
    if(ransom[i] > magazine[i]):
        yesNo = "No"
print(yesNo)

使用any

更短
yesno = "No" if any(random[i] > magazine[i] for i in ransom) else "Yes"