(FB) Phone Letter Combination

把这题单独拿出来,是因为这是个非常典型的递归 / 迭代都很直观的搜索类问题,一个 DFS,一个 BFS.

BFS 就靠 Queue,以 queue 首长度 == i 来判断层数,反复做 join. 另外维护一个 String[] 用作字典查询。

    public List<String> letterCombinations(String digits) {
        LinkedList<String> queue = new LinkedList<String>();
        if(digits == null || digits.length() == 0) return queue;

        queue.add("");
        String[] letters = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

        for(int i = 0; i < digits.length(); i++){
            int cur = digits.charAt(i) - '0';
            while(queue.peek().length() == i){
                String str = queue.remove();
                char[] candidates = letters[cur].toCharArray();
                for(char chr : candidates){
                    queue.add(str + chr);
                }
            }
        }

        return queue;
    }

DFS 写法就是做了无数次的 backtracking 写法。本质上,都是殊途同归的状态空间搜索罢了。

    public List<String> letterCombinations(String digits) {
        List<String> list = new ArrayList<String>();
        if(digits == null || digits.length() == 0) return list;
        String[] letters = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

        dfs(list, new StringBuilder(), digits, letters, 0);

        return list;
    }

    private void dfs(List<String> list, StringBuilder sb, String digits, String[] letters, int pos){
        if(sb.length() == digits.length()){
            list.add(sb.toString());
            return;
        }

        for(int i = pos; i < digits.length(); i++){
            String str = letters[digits.charAt(i) - '0'];
            for(int j = 0; j < str.length(); j++){
                int length = sb.length();
                sb.append(str.charAt(j));
                dfs(list, sb, digits, letters, i + 1);
                sb.setLength(length);
            }
        }
    }

Last updated