LeetCode.17 电话号码的字母组合

题目

LeetCode.17 电话号码的字母组合

解题思路

  1. 本题是给一个数字字符串,每个数字字符对应了一个字母字符串。求这些字母字符串之间,字母字符的排列组合
  2. 简单理解,就是每个数字都要拿出一个字母来进行组合,求有多少种不重复的组合。
  3. 先把数字映射成字母,然后再对每组字母进行排列组合

回溯思路

全局变量

  • 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,然后返回;

递归参数和返回值

  • 参数:
    1. String[] letter:数字对应的字母;
    2. int startIndex:每次 for 循环的开始位置,即当前循环从 letter 的哪个位置开始;
  • 返回值:
    1. 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);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值