1. 程式人生 > >leetcode 電話號碼的字母組合 Letter Combinations of a Phone Number

leetcode 電話號碼的字母組合 Letter Combinations of a Phone Number

給定一個數字字串,返回數字所有可能表示的字母組合。

下面給出數字到字母的對映(和電話號碼一樣)。

輸入:數字字串 "23"
輸出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

說明:
儘管上面的答案是按字典序排列的,但是你的答案可以是任何順序。

解答:

第一種方法是回溯法。

 public static List<String> letterCombinations(String digits) {
        List<String> list = new ArrayList<String>();
        if (digits.length()==0){
            return list;
        }
        backtracking("",digits,0,list);//回溯
        return list;
    }
    /*
     *比如輸入1,2。對應的是abc,def。回先從a開始,然後flag+1,依次向下遍歷def,
     * 然後依次向上返回返回ad,ae,af,並且新增到結果集中,然後再向上返回到i=0的迴圈
     * 然後i+1,從b開始,再依次向下遍歷def,如同a一樣,依次返回所有結果,當所有的遍歷完之和,返回到letterCombinations中結束。
     */
    public static void backtracking(String s,String digits,int flag,List<String> list){
        String[] strings = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
        if (flag >= digits.length()){如果已經遍歷完所有輸入的數字,說明已經到達底部,需要向上溯源。
            list.add(s);//到達底部說明已經是完整的一個結果,則將此次結果新增到結果集中
            return;//返回,向上回溯
        }

        String chars = strings[digits.charAt(flag) - '0'];
        for (int i = 0; i < chars.length(); i++) {//遍歷一個數字對應的所有字母

            backtracking(s + chars.charAt(i),digits,flag+1,list);//將當前字元加到s上並將flag+1迴圈下一個數字的字母
        }
    }

第二種方法是佇列進出法:

 public static List<String> letterCombinations(String digits) {
        Map<Integer,String> map = new HashMap<Integer,String>();
        map.put(0, "");
        map.put(1, "");
        map.put(2, "abc");
        map.put(3, "def");
        map.put(4, "ghi");
        map.put(5, "jkl");
        map.put(6, "mno");
        map.put(7, "pqrs");
        map.put(8, "tuv");
        map.put(9, "wxyz");

        List<String> result = new LinkedList<>();//結果集
        if(digits.length()==0){
            return result;
        }
        Queue<StringBuilder> queue = new LinkedList<>();//佇列
        queue.add(new StringBuilder());//先在佇列中新增一個新的空字串

        for (int i = 0; i < digits.length(); ++i){//迴圈所有輸入的數字
            int limitSize = queue.size();//記錄每次出佇列之前的元素的個數
            if (digits.charAt(i) == '0' || digits.charAt(i) == '1'){//如果數字是0或1,因為沒有對應的字母,則跳過
                continue;
            }
            int tar = digits.charAt(i) - '0';
            int j = 0;//用於將queue中的元素依次出佇列
            while (!queue.isEmpty() && j < limitSize){//迴圈j將limitsize個元素依次出佇列
                StringBuilder stringBuilder1 = queue.poll();//每次將佇列頭一個stringBuilder出佇列
                for (char x: map.get(tar).toCharArray()){//迴圈每一個數字對應的字母,依次加入到佇列中
                    StringBuilder tmp = new StringBuilder(stringBuilder1);//獲得每一個出對列的stringBuilder,並將後面的字母append到後面
                    tmp.append(x);
                    queue.add(tmp);//將stringBuilder加入到佇列中
                }
                ++j;
            }
        }
        while (!queue.isEmpty()){
            result.add(queue.poll().toString());//依次將佇列中的字串加入到結果集中
        }
        return result;
    }