题目
LeetCode.17 电话号码的字母组合
解题思路
本题是给一个数字字符串 ,每个数字字符对应了一个字母字符串 。求这些字母字符串之间,字母字符的排列组合 。 简单理解,就是每个数字都要拿出一个字母 来进行组合,求有多少种不重复的组合。 先把数字映射成字母 ,然后再对每组字母进行排列组合 。
回溯思路
全局变量
List<String> result :用于存放最终返回结果;StringBuilder str :用于存储每一个组合;String[10] map :用于存放数字到字母的映射;
在进行回溯之前的处理逻辑:
先将传入的数字字符串数组 digits 映射成对应的字母字符串数组,并将该字母字符串数组作为递归参数传入;
if ( digits. length ( ) == 0 ) return result;
String [ ] letter = new String [ digits. length ( ) ] ;
for ( int i = 0 ; i < digits. length ( ) ; i++ ) {
letter[ i] = map[ digits. charAt ( i) - '0' ] ;
}
回溯函数的作用
回溯函数 backtracking 用于判断当前 str 是否满足组合条件 ,若不符合,则继续加入字母。若符合,则把 str 加入 result,然后返回;
递归参数和返回值
参数:
String[] letter :数字对应的字母;int startIndex :每次 for 循环的开始位置,即当前循环从 letter 的哪个位置开始; 返回值:
void :没有返回值,结果直接存在 result 中;
public void backtracking ( String [ ] letter, int startIndex) { }
回溯结束条件
每个组合的字母个数,就是数字的个数(即 letter 的长度)。所以递归结束条件就是 字母个数 = 数字个数 。
if ( str. length ( ) == letter. length) {
result. add ( new String ( str) ) ;
return ;
}
单次回溯逻辑
从 startIndex 开始,遍历 letter; 然后再对 letter[startIndex] 中的每个字母进行遍历; 把当前字母加入 str 中,然后判断 str 是否满足组合条件。满足的话将 str 加入 result 并返回,不满足就进入下一层 循环,从 startIndex + 1 开始继续往 str 加入字母; 返回之后把字母从 str 中移除,继续下一次 循环,加入下一个字母,继续判断;
for ( int i = startIndex; i < letter. length; i++ ) {
for ( int j = 0 ; j < letter[ i] . length ( ) ; j++ ) {
str. append ( letter[ i] . charAt ( j) ) ;
combination ( letter, i + 1 ) ;
str. deleteCharAt ( str. length ( ) - 1 ) ;
}
}
完整代码(核心代码模式)
class Solution {
List < String > result = new ArrayList < > ( ) ;
StringBuilder str = new StringBuilder ( ) ;
String [ ] map = {
"" ,
"" ,
"abc" ,
"def" ,
"ghi" ,
"jkl" ,
"mno" ,
"pqrs" ,
"tuv" ,
"wxyz" } ;
public List < String > letterCombinations ( String digits) {
if ( digits. length ( ) == 0 ) return result;
String [ ] letter = new String [ digits. length ( ) ] ;
for ( int i = 0 ; i < digits. length ( ) ; i++ ) {
letter[ i] = map[ digits. charAt ( i) - '0' ] ;
}
combination ( letter, 0 ) ;
return result;
}
public void combination ( String [ ] letter, int startIndex) {
if ( str. length ( ) == letter. length) {
result. add ( new String ( str) ) ;
return ;
}
for ( int i = startIndex; i < letter. length; i++ ) {
for ( int j = 0 ; j < letter[ i] . length ( ) ; j++ ) {
str. append ( letter[ i] . charAt ( j) ) ;
combination ( letter, i + 1 ) ;
str. deleteCharAt ( str. length ( ) - 1 ) ;
}
}
}
}