https://oj.leetcode.com/problems/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.
解题思路:
针对输入的字符串digits,生成一个二维数组,横列是digits的每个字符,数列就是每个字符可能代表的字母。这里要注意,7和9可能代表4个字母,其他数字可能代表3个字母。
下面的问题就变成,每个字符选出一个字母,可能有多少种情况。比较典型的可以用dfs求解的问题。
public class Solution { public List<String> letterCombinations(String digits) { List<String> returnList = new ArrayList<String>(); if(digits.length() == 0){ return returnList; } char[][] chars = new char[digits.length()][4]; for(int i = 0; i < digits.length(); i++){ if(digits.charAt(i) >= '2' && digits.charAt(i) <= '6'){ for(int j = 0; j < 3; j++){ // if(j == 3){ // chars[i][j] = '1'; // } chars[i][j] = (char)('a' + (digits.charAt(i) - '0' - 2) * 3 + j); } } if(digits.charAt(i) >= '7' && digits.charAt(i) <= '9'){ if(digits.charAt(i) == '7'){ chars[i] = new char[]{'p','q','r','s'}; } if(digits.charAt(i) == '8'){ chars[i] = new char[]{'t','u','v'}; } if(digits.charAt(i) == '9'){ chars[i] = new char[]{'w','x','y','z'}; } } } StringBuffer bf = new StringBuffer(); dfs(returnList, chars, 0, bf); return returnList; } public static void dfs(List<String> returnList, char[][] chars, int start, StringBuffer bf){ if(start == chars.length){ returnList.add(bf.toString()); return; } for(int i = 0; i < chars[start].length; i++){ if(chars[start][i] == '\0'){ return; } bf.append(chars[start][i]); dfs(returnList, chars, start + 1, bf); bf.deleteCharAt(start); } } }
这里的dfs递归实际上只用到一个变量start,所以也可以将其他变量声明为成员变量。
public class Solution { List<String> returnList; char[][] chars; StringBuffer bf = new StringBuffer(); public List<String> letterCombinations(String digits) { returnList = new ArrayList<String>(); if(digits.length() == 0){ return returnList; } chars = new char[digits.length()][4]; for(int i = 0; i < digits.length(); i++){ if(digits.charAt(i) >= '2' && digits.charAt(i) <= '6'){ for(int j = 0; j < 3; j++){ // if(j == 3){ // chars[i][j] = '1'; // } chars[i][j] = (char)('a' + (digits.charAt(i) - '0' - 2) * 3 + j); } } if(digits.charAt(i) >= '7' && digits.charAt(i) <= '9'){ if(digits.charAt(i) == '7'){ chars[i] = new char[]{'p','q','r','s'}; } if(digits.charAt(i) == '8'){ chars[i] = new char[]{'t','u','v'}; } if(digits.charAt(i) == '9'){ chars[i] = new char[]{'w','x','y','z'}; } } } dfs(0); return returnList; } public void dfs(int start){ if(start == chars.length){ returnList.add(bf.toString()); return; } for(int i = 0; i < chars[start].length; i++){ if(chars[start][i] == '\0'){ return; } bf.append(chars[start][i]); dfs(start + 1); bf.deleteCharAt(start); } } }
当然,这道题也可以用bfs的方法,代码如下。
public class Solution { public List<String> letterCombinations(String digits) { List<String> returnList = new ArrayList<String>(); if(digits.length() == 0){ return returnList; } //对于2-6的数字,第四个字母为初始化,所以为'\u0000' char[][] chars = new char[digits.length()][4]; for(int i = 0; i < digits.length(); i++){ if(digits.charAt(i) >= '2' && digits.charAt(i) <= '6'){ for(int j = 0; j < 3; j++){ // if(j == 3){ // chars[i][j] = '1'; // } chars[i][j] = (char)('a' + (digits.charAt(i) - '0' - 2) * 3 + j); } } if(digits.charAt(i) >= '7' && digits.charAt(i) <= '9'){ if(digits.charAt(i) == '7'){ chars[i] = new char[]{'p','q','r','s'}; } if(digits.charAt(i) == '8'){ chars[i] = new char[]{'t','u','v'}; } if(digits.charAt(i) == '9'){ chars[i] = new char[]{'w','x','y','z'}; } } } //bfs方法 returnList.add(""); //第一层循环是digits所含有的数字数量 for(int i = 0; i < chars.length; i++){ List<String> tempReturnList = new ArrayList<String>(); //第二层循环是每个数字代表的字母数量 for(int j = 0; j < chars[i].length; j++){ //第三层循环是returnList里已经组成的字符串数量 for(int k = 0; k < returnList.size(); k++){ if(chars[i][j] == '\0'){ continue; } tempReturnList.add(returnList.get(k) + chars[i][j]); } } returnList = tempReturnList; } return returnList; } }
//20181202
前面编写电话号码的简单点
public class Solution { public List<String> letterCombinations(String digits) { List<String> returnList = new ArrayList<String>(); if(digits.length() == 0){ return returnList; } String[] telephone = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; String[] numbers = new String[digits.length()]; for (int i = 0; i < digits.length(); i++) { numbers[i] = telephone[digits.charAt(i) - '0']; } StringBuffer bf = new StringBuffer(); dfs(returnList, numbers, 0, bf); return returnList; } public static void dfs(List<String> returnList, String[] numbers, int start, StringBuffer bf){ if(start == numbers.length){ returnList.add(bf.toString()); return; } for(int i = 0; i < numbers[start].length(); i++){ bf.append(numbers[start].charAt(i)); dfs(returnList, numbers, start + 1, bf); bf.deleteCharAt(start); } } }