代码随想录算法训练营第二十五天| 216.组合总和III、17.电话号码的字母组合

发布于:2024-04-07 ⋅ 阅读:(118) ⋅ 点赞:(0)

系列文章目录



216.组合总和III

本题k相当于树的深度,9(因为整个集合就是9个数)就是树的宽度。
剪枝:①for循环的范围剪枝,i <= 9 - (k - path.size()) + 1就可以了。
②已选元素总和如果已经大于n(即n已经小于0了),那么往后遍历就没有意义了,直接剪掉。

import java.util.LinkedList;
class Solution {
    List<Integer> path = new LinkedList<>();
    List<List<Integer>> res = new LinkedList<>();

    public List<List<Integer>> combinationSum3(int k, int n) {
        backtracking(k, n, 1);
        return res;
    }

    public void backtracking(int k, int n, int startIndex) {
        //剪枝
        if (n < 0) return;
        if (path.size() == k) {
            if (n == 0) {
                res.add(new LinkedList<>(path));
            }
            return;
        }
        // 剪枝 9 - (k - path.size()) + 1
        for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) {
            path.add(i);
            n -= i;
            backtracking(k, n, i + 1);
            path.remove(path.size() - 1);	//回溯
            n += i;			//回溯
        }
    }
}

在这里插入图片描述


17.电话号码的字母组合

回溯法

  • 数字和字母的映射:为了直接对应2-9,新增了两个无效的字符串""String[] mapping = new String[] { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };,在得到映射坐标时,char类型-char类型,要用相应的ASCII码值减去0ASCII码值,int indexOfMap = digits.charAt(sb.length()) - '0';
  • 本题每一个数字代表的是不同集合,也就是求不同集合之间的组合。而 77. 组合216.组合 总和III 都是求同一个集合中的组合!故这两题需要用startIndex来记录遍历的起始位置。
  • 注意:输入1 * #按键等等异常情况。代码中最好考虑这些异常情况,但题目的测试数据中应该没有异常情况的数据,所以我就没有加了。但是要知道会有这些异常,如果是现场面试中,一定要考虑到!
import java.util.LinkedList;
class Solution {
    List<String> res = new LinkedList<>();
    StringBuilder sb = new StringBuilder();

    public List<String> letterCombinations(String digits) {
        //每个数字到字母的映射,为了直接对应2-9,新增了两个无效的字符串""
        String[] mapping = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        backTracking(digits, mapping, /*sb*/0);
        return res;
    }

    public void backTracking(String digits, String[] mapping, /*StringBuilder sb*/int num) {
        //终止条件
        if (/*sb.length()*/num == digits.length()) {
            res.add(sb.toString());
            return;
        }
        //单层递归逻辑
        //str 表示当前num对应的字符串
        int indexOfMap = digits.charAt(/*sb.length()*/num) - '0';//注意映射,要用相应的ASCII码值减去0的ASCII码值
        String str = mapping[indexOfMap];
        for (int i = 0; i < str.length(); i++) {
            sb.append(str.charAt(i));
            backTracking(digits, mapping, /*sb*/num + 1);
            sb.deleteCharAt(sb.length() - 1);//回溯
        }
    }
}

在这里插入图片描述



网站公告

今日签到

点亮在社区的每一天
去签到