Hackerrank | Hash Tables: Ransom Note解答

Hash Tables: Ransom Note原题点这里

第一次尝试:失败
def checkMagazine(magazine, note):
    for word in note:
        if word in magazine:   
            magazine.remove(word)  
        elif word not in magazine:
            print('No')
            return
    print('Yes')                  

非常直白的逻辑,可惜时间复杂度是O(mn),测试时有三个test cases出现timeout error。究其原因,还是array的remove操作太慢,最坏情况需要O(n)时间。

第二次尝试:失败
def checkMagazine(magazine, note):
    col1=set(magazine)
    col2=set(note)
    if col2.difference(col1)==set():
        print('Yes')
    else:
        print('No')

第二次,想到了利用数据结构集合的特性来直接检验note是否是magazine的子集。集合把问题更加简化了,几乎只需要调用difference这一个方法就可以达到目的。可惜的是,集合使用起来虽然方便,却不接受重复值,所以无法统计某个单词出现的词频。因此,集合还是没法满足这道题的要求。
ps:由于集合中无重复值的特性,集合可以用来删除列表中的重复值:只需要先把列表转化为集合,再转回list就可以了。

第三次尝试:成功
def checkMagazine(magazine, note):
    m={}
    for word in magazine: 
        if word not in m:  
            m[word]=1
        else:
            m[word]+=1
    for word in note:
        if word not in m or m[word]==0:
            print('No')
            return
        else:
            m[word]-=1
    print('Yes')

第三次使用了字典的数据结构(其实这道题名字里就有hash table,所以本来应该直接想到用字典的= =),先把magazine里的词存储到一个字典里。由于magazine中很有可能含有大量重复的单词,这个工作很有意义。第一次尝试中O(n)的array removal被更改字典数值这个O(1)的操作代替了,从而降低了时间复杂度。

你可能感兴趣的:(Python,算法)