17. Letter Combinations of a Phone Number

题目:

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

http://www.cnblogs.com/yrbbest/p/4433742.html

原文地址:https://www.cnblogs.com/panini/p/6692842.html