資料結構與演算法——提供一個單詞,在字典中找到它的兄弟

readyao發表於2015-12-26

題目:

 一個單詞單詞字母交換,可得另一個單詞,如 army->mary,成為兄弟單詞。提供一個單詞,在字典中找到它的兄弟。描述資料結構和查詢過程。(百度2012年實習生面試題)

解題思路:

http://superonion.iteye.com/blog/1522199

思路一:使用trie樹

在字典樹的字首中再儲存一個vector結構的容器:
Cpp程式碼
struct word  
{    
    vector<string> brother;    // 用於儲存每個單詞的兄弟單詞  
    word *next[26];            // 字典樹中每個節點代表一個字元,並指向下一個字元  
};  
如上述資料結構所示,字典樹的建立是在預處理階段完成的,首先根據字典中的單詞來建立字典樹,建立的時候,需要稍微特殊處理一下,就是比如pots、stop和tops互為兄弟單詞,那麼在字典中按照首字母順序的話,應該先遇到pots單詞,那麼我首先對其進行排序,結果是opts,那麼字典樹中就分別建立4個節點,分別為o->p->t->s,當然這個是不同層次的,在節點s處的vector容器brother中新增單詞pots,遇到stop的時候,同樣的方法,排序是opts,此時發現這4個節點已經建立了,那麼只需要在第四個節點s處的vector容器brother中新增單詞stop,tops單詞的處理方法是同樣的。

這樣建立完字典樹後,查詢兄弟單詞的效率就會很高了,比雜湊的效率還要高;查到tops的兄弟的單詞的時候,首先排序,那麼就是opts,然後在字典樹中查詢opts,在s處將其vector容器brother中的的單詞輸出就是tops的所有兄弟單詞。
 

思路二:使用hash_map和連結串列

首先定義一個key,使得兄弟單詞有相同的key,不是兄弟的單詞有不同的key。例如,將單詞按字母從小到大重新排序後作為其key,比如bad的key為abd,good的key為dgoo。 
使用連結串列將所有兄弟單詞串在一起,hash_map的key為單詞的key,value為連結串列的起始地址。 
開始時,先遍歷字典,將每個單詞都按照key加入到對應的連結串列當中。當需要找兄弟單詞時,只需求取這個單詞的key,然後到hash_map中找到對應的連結串列即可。 
這樣建立hash_map時時間複雜度為O(n),查詢兄弟單詞時時間複雜度是O(1)。
 

思路三:同樣使用hash_map和連結串列

將每一個字母對應一個質數,然後讓對應的質數相乘,將得到的值進行hash,這樣兄弟單詞的值就是一樣的了,並且不同單詞的質數相乘積肯定不同。
使用連結串列將所有兄弟單詞串在一起,hash_map的key為單詞的質數相乘積,value為連結串列的起始地址。
對於使用者輸入的單詞進行計算,然後查詢hash,將連結串列遍歷輸出就得到所有兄弟單詞。
這樣建立hash_map時時間複雜度為O(n),查詢兄弟單詞時時間複雜度是O(1)。

要掌握的知識:

字典樹:
又稱單詞查詢樹,Trie樹,是一種樹形結構,是一種雜湊樹的變種。
典型應用是用於統計,排序和儲存大量的字串(但不僅限於字串),所以經常被搜尋引擎系統用於文字詞頻統計。
它的優點是:利用字串的公共字首來減少查詢時間,最大限度地減少無謂的字串比較,查詢效率比雜湊樹高。
參考連結:
http://baike.baidu.com/link?url=fFhIr3z5eY9Qor37DOB8IwlMJZ65PVoyq29k7WY5bvI7g3dIyma2q7n0SuzRA2VK_-67p869_r7cUYKjMXCCYa
http://blog.csdn.net/hguisu/article/details/8131559

相關題目:

如果兩個字串的字元一樣,但是順序不一樣,被認為是兄弟字串,問如何在迅速匹配兄弟字串(如,bad和adb就是兄弟字串)。

思路:判斷各自素數乘積是否相等。更多方法請參考http://blog.csdn.net/v_JULY_v/article/details/6347454


相關文章