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)的操作代替了,從而降低了時間複雜度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章