题目描述:
给定一个数字字符串,返回数字所有可能表示的字母组合。
下面给出数字到字母的映射(和电话号码一样)。
输入:数字字符串 "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; }