前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >39. 组合总和

39. 组合总和

作者头像
张伦聪zhangluncong
发布2022-10-26 17:53:40
2240
发布2022-10-26 17:53:40
举报

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

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。 解集不能包含重复的组合。

示例 1:

代码语言:javascript
复制
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]

示例 2:

代码语言:javascript
复制
输入: candidates = [2,3,5], target = 8,
所求解集为:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

解:回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。核心代码就几行。

代码语言:javascript
复制
public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> results = new ArrayList<>();
        if (candidates == null || candidates.length == 0) {
            return results;
        }

        int[] nums = removeDuplicates2(candidates);

        dfs(nums, 0, new ArrayList<Integer>(), target, 0, results);

        return results;
    }

    /**
     * 排序去重复
     *
     * @param candidates
     * @return
     */
    private int[] removeDuplicates2(int[] candidates) {
        Arrays.sort(candidates);

        int index = 0;
        for (int i = 0; i < candidates.length; i++) {
            if (candidates[i] != candidates[index]) {
                candidates[++index] = candidates[i];
            }
        }

        int[] nums = new int[index + 1];
        for (int i = 0; i < index + 1; i++) {
            nums[i] = candidates[i];
        }

        return nums;
    }

    /**
     * 深度优先搜索
     *
     * @param nums        数组
     * @param startIndex  开始索引
     * @param combination 和的组合list
     * @param target      目标值
     * @param sum         和
     * @param results     结果
     */
    private void dfs(int[] nums,
                     int startIndex,
                     List<Integer> combination,
                     int target,
                     int sum,
                     List<List<Integer>> results) {
        if (sum == target) {
            results.add(new ArrayList<Integer>(combination));
            return;
        }

        for (int i = startIndex; i < nums.length; i++) {
            if (target < nums[i] + sum) {
                break;
            }
            combination.add(nums[i]);
            dfs(nums, i, combination, target, sum + nums[i], results);
            combination.remove(combination.size() - 1);
        }
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档