题目:
Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
Input:Digit string "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.
链接:https://leetcode.com/problems/letter-combinations-of-a-phone-number/#/description
4/10/2017
不理解backtracking,照着课件一点点尝试理解总结。
在recursive函数中,主要有下面几个注意方面:
1. 循环是当前层可以选择的值
2. 循环体内:
a. 加入本层新的值
b. 继续向下一层调用
c. 减去本层a中新加入的值
其他的问题:
1. 没有想到用数组表示题目中的map,以后长度小的时候应该用array
2. 重复不重复的问题不是靠变第4行的ret为set解决的,而是通过recursive function的循环范围来规定的。
1 public class Solution { 2 int N; 3 StringBuilder sb; 4 List<String> ret; 5 String[] phone = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; 6 7 public List<String> letterCombinations(String digits) { 8 ret = new ArrayList<>(); 9 if (digits == null || digits.length() == 0) return ret; 10 sb = new StringBuilder(); 11 N = digits.length(); 12 enumerate(0, digits); 13 return ret; 14 } 15 private void process(StringBuilder sb) { 16 ret.add(sb.toString()); 17 } 18 private void enumerate(int k, String digits) { 19 if (k == N) { 20 process(sb); 21 return; 22 } 23 int v = digits.charAt(k) - '0'; 24 for (int j = 0; j < phone[v].length(); j++) { 25 sb.append(phone[v].charAt(j)); 26 enumerate(k + 1, digits); 27 sb.deleteCharAt(sb.length() - 1); 28 } 29 } 30 }
课件:
https://www.cs.princeton.edu/courses/archive/fall12/cos226/lectures/67CombinatorialSearch.pdf
别人的算法:
用BFS做的,还没有看明白
1. 注意ans的数据结构是LinkedList,所以可以是用peek
2. 第7行验证当前结果里的是下一个要处理的string,因为ans是linkedlist,这里当作queue来使用
3. 第8行将还没有处理到的string取出来,并在第9,10行中对他分别加入当前index应该加入的char
4. 当前index元素都插入时,第7行判断的元素长度会比i多1,当前index结束
[""]
["a", "b", "c"]
["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"],中间的某个时刻["b", "c", "ad", "ae", "af"]下一步就会把def加入b的后面
https://discuss.leetcode.com/topic/8465/my-java-solution-with-fifo-queue
1 public List<String> letterCombinations(String digits) { 2 LinkedList<String> ans = new LinkedList<String>(); 3 String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; 4 ans.add(""); 5 for(int i =0; i<digits.length();i++){ 6 int x = Character.getNumericValue(digits.charAt(i)); 7 while(ans.peek().length()==i){ 8 String t = ans.remove(); 9 for(char s : mapping[x].toCharArray()) 10 ans.add(t+s); 11 } 12 } 13 return ans; 14 }
别人的DFS
较少用到全局变量
https://discuss.leetcode.com/topic/6380/my-recursive-solution-using-java
1 public class Solution { 2 private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; 3 4 public List<String> letterCombinations(String digits) { 5 List<String> ret = new LinkedList<String>(); 6 combination("", digits, 0, ret); 7 return ret; 8 } 9 10 private void combination(String prefix, String digits, int offset, List<String> ret) { 11 if (offset >= digits.length()) { 12 ret.add(prefix); 13 return; 14 } 15 String letters = KEYS[(digits.charAt(offset) - '0')]; 16 for (int i = 0; i < letters.length(); i++) { 17 combination(prefix + letters.charAt(i), digits, offset + 1, ret); 18 } 19 } 20 }
更多讨论:
https://discuss.leetcode.com/category/25/letter-combinations-of-a-phone-number