39组合总和

题目描述

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

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

说明:

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

示例 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]
]

思路分析

回溯问题。三要素。dfs+剪枝。

路径:已经加入的数字。

选择列表:还能选择加入的数字。

结束条件:sum==target;sum > target。

这种写法还能继续优化,比如2,2,2,2 > 7,则后续的2223,2226,2227都可以不用进入函数,直接跳出。

代码实现

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> lists = new ArrayList<>();
        if (candidates == null || candidates.length == 0) {
            return lists;
        }
        if (candidates == null || candidates.length == 0 || target == 0) {
            return lists;
        }
        process(candidates, target, lists, 0, new ArrayList<>(), 0);
        return lists;
    }

    public void process(int[] candidates, int target, List<List<Integer>> lists, int sum, List<Integer> list, int i) {
        if (sum > target || i > candidates.length - 1) {
            return;
        }

        if (sum == target) {
            lists.add(new ArrayList<>(list));
        }
        //这里还能继续优化,比如2222超出,后面就不用再继续2223,2226,因为必然超出
        for (int j = i; j < candidates.length; j++) {
            sum += candidates[j];
            list.add(candidates[j]);
            process(candidates, target, lists, sum, list, j);
            list.remove(list.lastIndexOf(candidates[j]));
            sum -= candidates[j];
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章