LeetCode - 40. Combination Sum II

发布于 2024-10-31 11:47:15 字数 3758 浏览 5 评论 0

题目

解析

这题和 LeetCode - 39 . Combination Sum 不同的地方在于:

  • LeetCode - 39 . Combination Sum 数组没有重复的元素,但是你可以使用同一个位置的元素去组成 target
  • 而此题,数组中可能存在重复的元素,但是你不能使用同一个位置的元素
  • 由于这一题可以使用不同位置上值相同的元素,所以 dfs 得到的结果 res 中可能存在重复的答案,例如第一个示例中,如果不去重,答案会是 [1, 7], [1, 7], [1, 2, 5], [1, 2, 5], [2, 6], [1, 1, 6] ,可以看到有两个重复的答案。所以需要去重。下面给出两种代码实现去重的方式。

① 其实只需要在 LeetCode - 39 . Combination Sum 的基础上加上一行代码,当有连续重复(在排序之后) 的值时,跳过即可,即 while(i+1 < nums.length && nums[i] == nums[i+1]) i++;

import java.io.*;
import java.util.*;

class Solution {

    private List<List<Integer>>res;

    //不同点: 不能使用同一个位置上的元素,但是不同位置上可能有相同值的元素,所以-->需要考虑重复答案的问题
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        res = new ArrayList<>();
        if(candidates == null || candidates.length == 0)
            return res;
        Arrays.sort(candidates); //先排序 ,既可以剪枝,由导致相邻相等的元素在一起
        dfs(candidates, target, 0, 0, new ArrayList<>());
        return res;
    }

    private void dfs(int[] nums, int target, int curSum, int cur, List<Integer>curr){ 
        if(curSum == target){ 
            res.add(new ArrayList<>(curr));
            return;
        }
        for(int i = cur; i < nums.length; i++){ 
            if(curSum + nums[i] > target) 
                break; // 因为排序了,所以这里是 break,不是 continue,剪枝
            curr.add(nums[i]);
            dfs(nums, target, curSum + nums[i], i+1, curr); // notice is i+1             
            curr.remove(curr.size()-1);
            while(i+1 < nums.length && nums[i] == nums[i+1]) i++; //only add this;
        }
    }

    public static void main(String[] args){
        PrintStream out = System.out;
        int[] candidates = {10, 1, 2, 7, 6, 1, 5};
        int target = 8;
        out.println(new Solution().
            combinationSum2(candidates, target)
        );
    }
}

② 或者在递归之前判断一下和前面的 nums[i-1] 是不是相同,即: if(i != cur && nums[i] == nums[i-1]) continue;

class Solution {

    private List<List<Integer>>res;

    //不同点: 不能使用同一个位置上的元素,但是不同位置上可能有相同值的元素,所以-->需要考虑重复答案的问题
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        res = new ArrayList<>();
        if(candidates == null || candidates.length == 0)
            return res;
        Arrays.sort(candidates); //先排序 ,既可以剪枝,由导致相邻相等的元素在一起
        dfs(candidates, target, 0, 0, new ArrayList<>());
        return res;
    }

    private void dfs(int[] nums, int target, int curSum, int cur, List<Integer>curr){ 
        if(curSum == target){ 
            res.add(new ArrayList<>(curr));
            return;
        }
        for(int i = cur; i < nums.length; i++){ 
            if(curSum + nums[i] > target) 
                break; 
            if(i != cur && nums[i] == nums[i-1])// judge this 
                continue;
            curr.add(nums[i]);
            dfs(nums, target, curSum + nums[i], i+1, curr); // notice is i+1             
            curr.remove(curr.size()-1);
        }
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

那些过往

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

玍銹的英雄夢

文章 0 评论 0

我不会写诗

文章 0 评论 0

十六岁半

文章 0 评论 0

浸婚纱

文章 0 评论 0

qq_kJ6XkX

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文