Leetcode 组合总和 II

在这里插入图片描述

这道题必须去重,去重又需要先进行排序。

当然可以!下面是一份适用于 LeetCode 40(组合总和 II)的**“思路总览”模板答案**,适合写在笔试或面试中,逻辑清晰、结构规范、面试官友好:


✅ 题目思路总览:LeetCode 40. 组合总和 II

🧩 题目理解:

给定一个可能包含重复数字的数组 candidates,和一个目标数 target,要求找出所有不重复的组合,使得组合中元素的和为 target每个数字只能使用一次


🔍 解题思路:

1. 排序 + 回溯
  • 首先对 candidates 进行升序排序,方便后续去重和剪枝操作。
  • 使用回溯算法(Backtracking)探索所有可能的组合路径。
  • 每一步选择当前数,并递归向后查找剩余目标 remain - candidates[i]
2. 去重处理
  • 避免相同元素在同一层递归中出现两次,使用:
    if (i > start && candidates[i] == candidates[i - 1]) continue;
    
  • 该逻辑必须建立在数组有序的前提下。
3. 剪枝优化
  • 如果当前元素已经大于剩余值 remain,由于数组有序,后续也无需继续搜索,直接 break

⏱ 时间复杂度分析(近似估算):

  • 最坏情况下,回溯会遍历所有子集,时间复杂度接近 O(2^n),但因为有剪枝+去重,实际远小于此。
  • 空间复杂度为 O(n)(递归栈 + 路径空间)

✅ 总结关键词:

  • 回溯(Backtracking)
  • 排序 + 去重
  • 剪枝优化
  • 每个元素只能用一次(控制递归起点)

java solution

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<>();
        //因为需要去重, 所以首先必须排序
        Arrays.sort(candidates);
        backtrack(0, target, new ArrayList<>(), candidates, result);
        return result;
    }
    
    private void backtrack(int start, int remain, List<Integer> list,int[] candidates, List<List<Integer>> result) {
        //先判断是否满足期望条件
        if(remain == 0) {
            result.add(new ArrayList<>(list));
            return;
        }

        for(int i = start; i < candidates.length; i++) {
            //因为题目要求不能有重复元素, 所以需要首先去重
            if(i > start && candidates[i] == candidates[i - 1]) continue;

            //剪枝
//之所以用的是 break 而不是 continue,关键点在于已经对 candidates 做了排序。
//当你遇到一个数 candidates[i] > remain,说明这个数已经比剩余目标值还大了:
//那么 后面更大的数也一定无法组成合法组合
//所以,继续遍历没有意义,可以直接终止循环
            if(candidates[i] > remain) break;
            //添加一个元素
            list.add(candidates[i]);
            //回溯判断
            backtrack(i + 1, remain - candidates[i], list, candidates, result);

            //撤销
            list.remove(list.size() - 1);
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值