尋找兄弟單詞(2012.5.6百度實習)


題目:一個單詞單詞字母交換,可得另一個單詞,如army->mary,成為兄弟單詞。提供一個單詞,在字典中找到它的兄弟。描述數據結構和查詢過程。

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

解法二:同樣使用hash_map和鏈表
(1)將每一個字母對應一個質數,然后讓對應的質數相乘,將得到的值進行hash,這樣兄弟單詞的值就是一樣的了,並且不同單詞的質數相乘積肯定不同。
(2)使用鏈表將所有兄弟單詞串在一起,hash_map的key為單詞的質數相乘積,value為鏈表的起始地址。
(3)對於用戶輸入的單詞進行計算,然后查找hash,將鏈表遍歷輸出就得到所有兄弟單詞。
這樣創建hash_map時時間復雜度為O(n),查找兄弟單詞時時間復雜度是O(1)。

如果是海量詞典的話,可以用B+樹。。。。。

注:上述兩種方法是比較高效的算法,一下介紹一種普通方法:

解法三:全排列,然后依次比較
看到這個題目后,直覺是可能是這樣的:求出輸入單詞的全部變換(假如單詞的長度是n,則其全部變換有n!個。如果有相同的字母就不是n!了),求出單詞的變換后,判斷每個變換是否在字典中。例如對於輸入abc,則其變換有3!=6種:abc、acb、bca、bac、cab、cba。然后在依次判斷這6個單詞(當然這里不是單詞了,而是字符串)是否在字典中,如果在字典中則記錄下來。
很明顯這種思想的復雜度是比較高的,因為對於n稍微大點的話,n!是一個很可怕的遞增過程,因此這個方法是不太可取的。
以下是全排列代碼:

/**
     * @param src
     * @param start 起始位置索引
     * @param end  結束位置索引
     */
   public static void perm(String[] src,int start,int end){
        if(start==end){//當只要求對數組中一個字母進行全排列時,只要按該數組輸出即可
            for(int i=0;i<=end;i++){
                System.out.print(src[i]);
            }
            System.out.println();
        }
        else{//多個字母全排列
            for(int i=start;i<=end;i++){
                String temp=src[start];//交換數組第一個元素與后續的元素
                src[start]=src[i];
                src[i]=temp;
                perm(src,start+1,end);//后續元素遞歸全排列
                temp=src[start];//將交換后的數組還原
                src[start]=src[i];
                src[i]=temp;
            }
        }
    }

將字典中的和‘比較單詞’首字母相同的單詞取出存放到一個數組中,將每一個組合和字典中的單詞比較。首先比較單詞長度,長度相同,則繼續比較;否則,比較下一個單詞。算法如下:

/**
     * @param src 字典中的單詞
     * @param des 要比較的單詞,因為要做大量比較,所以轉化為字符數組
     * @return
     */
    public static boolean compare(String src,String[] des){
        int len = src.length();
        if(len != des.length){//如果長度不相等,肯定不是兄弟單詞,則無需比較
            return false;
        }
        int i = 1;//i等於1是因為首字符已經相同,無需比較
        while(i<len){
            if(des[i].equals(String.valueOf(src.charAt(i)))){
                i++;
                continue;
            }
            return false;
        }
        return true;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM