[Leetcode] 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"].
原来的问题是给定一个由数字组成的字符串,求这些数字在电话按键上对应的字母的所有组合。我们考虑使用动态规划来解决这个问题。假设这个字符串中的数字从左到右依次为C1, C2, ..., Cn,共n个数字,现在考虑能否把这个问题转化成一个规模更小,但是性质类似的问题,即当已经找到给定字符串包含C1, C2, ..., Cn-1这前n-1个数字的字母组合时,怎样求出再加一个数字的字母组合
以数字串"23"为例,假设已经求出“2”对应的字母组合为{"a","b","c"},那么怎样能求出“23”对应的字母组合呢?可以从集合{"a","b","c"}中每次取出一个字符串,然后与3对应的三个字母d, e, f分别拼接成一个新字符串,这样就得到了“23”对应的所有字母组合,即{"ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"}.
将上述的简单情况推广到一般情况,就可以解决最开始的问题。从包含一个空字符串的集合开始{""},按照从左到右的顺序,从C1, C2, ..., Cn 中每次取一个数字,将Ci对应的每个字母与集合中的每个字符串进行拼接,得到一个新的字符串集合,后面的一轮针对Ci+1的拼接再基于这个新的集合。
Java实现的算法如下:
1 public class Solution1 { 2 public List<String> letterCombinations(String digits) { 3 String[] mapping = new String[]{"", "", "abc", "def", "ghi", 4 "jkl", "mno", "pqrs", "tuv", "wxyz"}; 5 List<String> lastList = new ArrayList<String>(); 6 if(digits == null || digits.length() == 0) { 7 return lastList; 8 } 9 lastList.add(""); 10 List<String> workList = new ArrayList<String>(); 11 for(int i = 0; i < digits.length(); i++) { 12 int digit = Integer.parseInt(String.valueOf(digits.charAt(i))); 13 for(String str : lastList) { 14 for(int j = 0; j < mapping[digit].length(); j++) { 15 StringBuilder sb = new StringBuilder(str); 16 sb.append(mapping[digit].charAt(j)); 17 workList.add(sb.toString()); 18 } 19 } 20 21 List<String> tmp = lastList; 22 lastList = workList; 23 workList = tmp; 24 25 workList.clear(); 26 } 27 28 return lastList; 29 } 30 }