当前位置: 首页 > news >正文

leetcode刷题记录(一百一十八)——39. 组合总和

(一)问题描述

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例 1:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例 2:

输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:

输入: candidates = [2], target = 1
输出: []

提示:

  • 1 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • candidates 的所有元素 互不相同
  • 1 <= target <= 40

(二)解决思路

        组合问题,回溯的经典问题。这里和一般回溯组合问题的区别在于求和,需要用一个sum变量来统计每组的和并进行判断。回溯的终止条件即sum==target。

        除此之外,一个数字可以使用多次也是一个重要信息,这代表每次搜索的起始位置与这一次搜索是相同的,即当前这个数字可以被多次选取。

        这个问题可以进行一些剪枝操作来减少不必要的操作:将整个数组排序,随后在找符合条件的组合时,如果某个组合的和已经大于了target,其后面的组合一定不满足要求(正整数数组,且按从小到大排序),这时可以直接跳出循环了。

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(candidates); // 先进行排序
        backtracking(res, new ArrayList<>(), candidates, target, 0, 0);
        return res;
    }

    public void backtracking(List<List<Integer>> res, List<Integer> path, int[] candidates, int target, int sum, int idx) {
        // 找到了数字和为 target 的组合
        if (sum == target) {
            res.add(new ArrayList<>(path));
            return;
        }

        for (int i = idx; i < candidates.length; i++) {
            // 如果 sum + candidates[i] > target 就终止遍历
            if (sum + candidates[i] > target) break;
            path.add(candidates[i]);
            backtracking(res, path, candidates, target, sum + candidates[i], i);
            path.remove(path.size() - 1); // 回溯,移除路径 path 最后一个元素
        }
    }
}

(三)易错点

        在Java中,只有引用类型变量的值可以在函数中被改变。因此在回溯函数中,sum+candidates[i]这一步要在调用函数时在参数内完成,在外部计算完sum的新值再到函数中使用sum使无法改变sum值的,结果会出错。

相关文章:

  • clickhouse--本地表和分布式表,副本机制,分片集群
  • c++ 典型练习题
  • MongoDB 查询文档
  • Python解决“数字分组求偶数和”问题
  • 如何实现网关
  • 课程分享 | 安全系统建设的挑战与解决方案
  • 【DeepSeek】CherryStudio + Ollama
  • FreiHAND (handposeX-json 格式)数据集-release >> DataBall
  • Springboot 熔断,穿透,雪崩
  • 网络安全-新型路径攻击流程及防御措施
  • 【论文精读】YOLO-World:实时开放词汇目标检测
  • 【无人集群系列---无人机集群编队算法】
  • Qt中C++与QML交互从原理、方法与实践陷阱深度解析
  • List的模拟实现(2)
  • 远程部署 Qt 应用程序套件错误原因
  • maven编译出错,javac: ��Ч��Ŀ�귢�а�: 17
  • 基于SpringBoot和Leaflet的邻省GDP可视化实战
  • 二叉树的遍历知识点及习题
  • 项目升级Sass版本或升级Element Plus版本遇到的问题
  • 文件包含-session2
  • 中华人民共和国和巴西联邦共和国关于强化携手构建更公正世界和更可持续星球的中巴命运共同体,共同维护多边主义的联合声明
  • 郑培凯:汤显祖的“至情”与罗汝芳的“赤子之心”
  • 【社论】人工智能将为教育带来什么
  • 祝贺!苏翊鸣成功解锁“2160”
  • 雷军:过去一个多月是创办小米以来最艰难的时间
  • 新华每日电讯:给“男性妇科病论文”开一剂复方药