17 Letter Combinations of a Phone Number
手机上每个数字按钮旁边都有3-4个字母,输入数字字符串,输出可能的字母组合。
例如输入:”23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
思路:建立每个数字和对应字母的映射关系。该个处理每一位数字,遍历每个数字可能的取值。按照递归去实现很简单。
private List<String> result = new ArrayList<String>();
private static Map<Integer, List<Character>> numberMap = new HashMap<Integer, List<Character>>();
static{for(int i=2;i<7;i++){numberMap.put(i, new ArrayList<Character>());for (int j = 0; j < 3; j++) {char ch = (char) ('a' + 3 * (i - 2) + j);numberMap.get(i).add(ch);}}numberMap.put(7, new ArrayList<Character>());numberMap.get(7).add('p');numberMap.get(7).add('q');numberMap.get(7).add('r');numberMap.get(7).add('s');numberMap.put(8, new ArrayList<Character>());numberMap.get(8).add('t');numberMap.get(8).add('u');numberMap.get(8).add('v');numberMap.put(9, new ArrayList<Character>());numberMap.get(9).add('w');numberMap.get(9).add('x');numberMap.get(9).add('y');numberMap.get(9).add('z');}
public List<String> letterCombinations(String digits) {result.clear();StringBuilder str = new StringBuilder(digits.length());str.setLength(digits.length());if(digits.length()>0){robot(0, digits, str);}return result;
}private void robot(int idx, String digits, StringBuilder r) {if (idx >= digits.length()) {result.add(r.toString());return;}int n = digits.charAt(idx) - 48;if (n < 2)return;for(char ch : numberMap.get(n)){r.setCharAt(idx, ch);robot(idx + 1, digits, r);}
}
收获1
嗯代码够丑的。看别人怎么处理映射关系。我怎么没想到呢。之前也有这样一个例子,当数字作为map的key的时候,选择用数组代替map,可能会是一种比较优雅的方式。
String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
收获2
一次性给stringBuider 一定的长度。这个做法在字符串中还是有点变扭。这个想法是从数组那里继承过来的。可以使用字符串相加的方式。
private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
private List<String> result = new ArrayList<String>();public List<String> letterCombinations(String digits) {result.clear();robot(0, digits, "");return result;
}private void robot(int idx, String digits, String prefix) {if (idx >= digits.length()) {if (prefix.length() > 0) {result.add(prefix);}return;}int n = digits.charAt(idx) - 48;if (n < 2)return;String letters = KEYS[n];for (int i = 0; i < letters.length(); i++) {robot(idx + 1, digits, prefix + letters.charAt(i));}
}
收获3
我是没法用递推的方式实现的,只能用递归。看看别人怎么做。其实从上一个递归的代码是可以得到一些启示的。当然这是“马后炮”的想法–看到别人这么做觉得应该想到的。但是之前我一直在用for去思考。
public List<String> letterCombinations(String digits) {LinkedList<String> ans = new LinkedList<String>();String[] mapping = new String[] { "0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };ans.add("");for (int i = 0; i < digits.length(); i++) {int x = Character.getNumericValue(digits.charAt(i));while (ans.peek().length() == i) {String t = ans.remove();for (char s : mapping[x].toCharArray())ans.add(t + s);}}return ans;}
参考链接
1 链接1
2 链接2