前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

35.算法学习之组合总数‖

qiguaw 2024-11-24 20:40:39 资源文章 9 ℃ 0 评论

题目:给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次。

说明: 解集不能包含重复的组合

示例

输入: candidates = [10,1,2,7,6,1,5], target = 8

所求解集为:

[

[1, 7],

[1, 2, 5],

[2, 6],

[1, 1, 6]

]


我的思路: 该题目和上一个题目一样,是求的全排列。 但和上一题要求不同的是,该题目的输入数组存在重复数据,而且每个元素只能被选取一次,当然结果集也不能有重复。那么我们这个题目该怎么做呢? 可以参考33题的去重思想(有相同值的元素,每个元素只能被选取一次) 和34题结果集不重复的思路。 我们的代码如下:

public static List<List<Integer>> combinationSum3(int[] candidates, int target) {
        Arrays.sort(candidates);
        List<List<Integer>> res = new ArrayList<>();
        back3(candidates, target, 0, new boolean[candidates.length], new ArrayList<>(), res);
        return res;
    }

    public static void back3(int[] candidates, int target, int cur, boolean[] used, List<Integer> pick, List<List<Integer>> res) {
        if (target == 0) {
            res.add(new ArrayList<>(pick));
            return;
        }
        if (pick.size() == candidates.length || cur == candidates.length) {
            return;
        }
        for (int i = cur; i < candidates.length; i++) {
            //相同元素每个元素选取一次
            if (used[i] || (i > 0 && candidates[i] == candidates[i - 1] && !used[i - 1])) {
                continue;
            }
            //减枝
            if (target - candidates[i] >= 0) {
                used[i] = true;
                pick.add(candidates[i]);
                back3(candidates, target - candidates[i], i + 1, used, pick, res);
                used[i] = false;
                pick.remove(pick.size() - 1);
            } else {
                //因为数组是排序过的, 若走到这一步,说明后面数字肯定更大,直接返回
                break;
            }
        }
    }

以上就是我的代码了。当然,大佬们有其他解法也可以指点一下。谢谢!

如果对您有帮助,帮忙点个赞呐~ : )

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表