电话号码的字母组合
问题链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
一、问题描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
二、问题分析
为了能定位到每个数字对应的字母使用一个二维数组来保存这个键盘String[i][str],i表示数字,str表示这个数字下的所有字母。为了保证当前字母被取用过,还应该有一个二维数组来对应这个字母是否被使用过。
那么现在的数据结构有两个,一个用来存储所有字母的二维数组,用于取用数据,一个用来判断字母是否被使用的二维数组。其实也可以用一维数组存储键盘,然后用String提供的方法将串分割就行
三、算法及代码
算法:使用回溯法,代码中给出的算法是广度优先搜索,是通过不断把外层的字母传给内层,然后通过内层返回结果,同时在内层使用完外层的字母时,在stringbuffer临时变量中会删除当前层的字母,这样可以用于当前层的下一个字母的循环。
1 class Solution { 2 public List<String> letterCombinations(String digits) { 3 String[] keybord = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; 4 //为使下标对应键盘数字,所以空开0和1位置 5 List<String> combinations = new ArrayList<String>();//这是一个部分解 6 if (digits.length() == 0) {//特殊情况 7 return combinations; 8 } 9 comstr(combinations, keybord, digits, 0, new StringBuffer()); 10 return combinations; 11 } 12 13 //使用该方法进行组串 14 /** 15 List<String> combinations:结果链表,用来不断修改结果 16 String keybord:键盘映射,用来取字母 17 String digits:输入数字组合 18 int index:一个指针,表示该方法求解digits中以index开始的子串的字母组合 19 StringBuffer combination 用来不断将新字符加入数组 20 */ 21 public void comstr (List<String> combinations,String[] keybord,String digits,int index, StringBuffer combination){ 22 if (index == digits.length()) {//递归边界,如果index超出串长度就返回一个空 23 combinations.add(combination.toString()); 24 } else { 25 Character cdigit = digits.charAt(index);//从测试用例中取出对应的数字 26 int digit = cdigit.getNumericValue(cdigit);//将数字转成int型 27 String letters = keybord[digit];//找到数字对应的字母 28 int lettersCount = letters.length();//统计该数字对应串长度 29 for (int i = 0; i < lettersCount; i++) { 30 combination.append(letters.charAt(i));//将本层的字母加入stringbuffer,并且传给下层 31 comstr(combinations, keybord, digits, index + 1, combination); 32 combination.deleteCharAt(index);//下层使用完后删除传入的字母,这样才能用于下次循环 33 } 34 } 35 } 36 }