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;
}