3

LeetCode HOT 100:组合总和 - 煜航

 1 year ago
source link: https://www.cnblogs.com/yuhang-wiki/p/16980572.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

题目:39. 组合总和

题目描述:

给你一个没有重复元素的数组,和一个target目标值,返回数组中可以使数字和为目标数target所有不同组合。什么叫组合?组合就是数组中任意数字组成的集合,不需要连续,组合和顺序无关。这一题中的不同,指的是两个组合中至少一个数字的被选数量不同,例如[2, 3, 3][2, 3, 2]就是同一个组合,反之则是不同。

这道题是很典型的回溯。回溯其实就是穷举,最多加点剪枝优化一下。所以这题思想就很简单,把每个元素不断穷举,判断其和是否达到了target

本题主要是回溯方法怎么写,所以下面步骤是回溯方法的步骤。
1、先定义好回溯方法的入参
这一题入参也很简单,数组,还需要凑齐的和,要从哪个下标开始穷举
2、定义好回溯方法后,方法里首先确定回溯结束的条件
这一题回溯结束条件就是:还需要凑齐的和为0了,说明该终止本次回溯了
3、定义好终止条件,下面就是开始穷举,伪代码如下

for (int i = startIndex; i < candidates.length; i++) {
	将元素放入数组
	迭代回溯方法
	将元素从数组中删除,回溯
}

1、本题使用了回溯模版,可以解决很多类似问题,回溯模版在这里总结一下。

void process(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本次递归集合中元素(从开始下标到数组结尾)) {
        处理节点;
        process(参数); // 递归
        回溯,撤销处理结果
    }
}
    List<List<Integer>> ans;
    List<Integer> list;

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        ans = new ArrayList<>();
        list = new ArrayList<>();

        // 从下标0开始,需要凑齐target的数
        process(candidates, target, 0);

        return ans;
    }

    // rest:剩下要凑齐的数字
    // startIndex:从哪个下标开始,继续拿值尝试
    public void process(int[] candidates, int rest, int startIndex) {
        // 剩余要凑的数字为0,说明target已经达到了,放进结果集合中
        if (rest == 0) {
            ans.add(new ArrayList<>(list));
            return;
        }

        // 从startIndex下标开始取值尝试
        for (int i = startIndex; i < candidates.length; i++) {
            // 如果当前值 > 剩下要凑齐的数字,那这个值就不用考虑了
            if (candidates[i] <= rest) {
                // 先将值放进数组
                list.add(candidates[i]);
                // 去递归找剩下要凑齐的rest - candidates[i]值
                // 因为每个数可以无限取,所以下次尝试还是从 i 开始,而不是 i + 1
                process(candidates, rest - candidates[i], i);
                // 将刚才放进去的值删除,回溯
                list.remove(list.size() - 1);
            }
        }
    }

__EOF__

本文作者: 煜航 本文链接: https://www.cnblogs.com/yuhang-wiki/p/16980572.html 关于博主: 评论和私信会在第一时间回复。或者直接私信我。 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK