leetcode(39)- 组合总和

题目

39.组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。
说明:
1.所有数字(包括 target)都是正整数。
2.解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]

参考

参考代码

思路

这种几个数加和组成某个数的全部情况都可以通过画树来解决。
在这里插入图片描述
如图可以看出:
1.我们要的所有情况就是叶子节点的值为0的情况。
2.当节点的值小于零的时候我们不再继续向下搜索。
3.根据上两条我们采用深度优先搜索算法,使用之前对数组从小到达排序,进行一部分的剪枝。
深度优先搜索算法模板:

void dfs(int step)
{
        if(满足终止搜索条件)
        {
            终止搜索,记录数据;
            return;
        }
        
        尝试每一种搜索可能
        {
               if(不满足继续搜索的条件)
               {
					跳过这一种搜索可能;
			   }
			   
			   记录搜索数据;
               继续下一步dfs(step+1);
               恢复初始状态(回溯的时候要用到);
        }
}   

实现代码:

class Solution {

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<>();
        int len = candidates.length;

        // 排序是为了提前终止搜索
        Arrays.sort(candidates);

        dfs(candidates, len, target, 0, new ArrayDeque<>(), res);
        return res;
    }

    /**
     * @param candidates 数组输入
     * @param len        输入数组的长度,冗余变量
     * @param residue    剩余数值
     * @param begin      本轮搜索的起点下标
     * @param path       从根结点到任意结点的路径
     * @param res        结果集变量
     */
    private void dfs(int[] candidates,
                     int len,
                     int residue,
                     int begin,
                     Deque<Integer> path,
                     List<List<Integer>> res) {
        if (residue == 0) {
            // 由于 path 全局只使用一份,到叶子结点的时候需要做一个拷贝
            res.add(new ArrayList<>(path));
            return;
        }

        for (int i = begin; i < len; i++) {

            // 在数组有序的前提下,剪枝
            if (residue - candidates[i] < 0) {
                break;
            }

            path.addLast(candidates[i]);
            dfs(candidates, len, residue - candidates[i], i, path, res);
            path.removeLast();
        }
    }
}
发布了53 篇原创文章 · 获赞 5 · 访问量 2223

猜你喜欢

转载自blog.csdn.net/qq_37668436/article/details/104636104
今日推荐