leetcode 电话号码的字母组合 Letter Combinations of a Phone Number

题目描述:

给定一个数字字符串,返回数字所有可能表示的字母组合。

下面给出数字到字母的映射(和电话号码一样)。

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

说明:
尽管上面的答案是按字典序排列的,但是你的答案可以是任何顺序。


解答:

第一种方法是回溯法。

扫描二维码关注公众号,回复: 884458 查看本文章
 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;
    }


猜你喜欢

转载自blog.csdn.net/wanderlustlee/article/details/79750110