Leetcode(Java)-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]
]

思路:参考全排的回溯思路

List> res = new LinkedList<>();
 
/* 主函数,输入一组不重复的数字,返回它们的全排列 */
List> permute(int[] nums) {
    // 记录「路径」
    // 这里的 选择列表 即包含在nums中
    LinkedList track = new LinkedList<>();
    backtrack(nums, track);
    return res;
}
 
// 路径:记录在 track 中
// 选择列表:nums 中的元素
// 结束条件:nums 中的元素全都在 track 中出现
void backtrack(int[] nums, LinkedList track) {
    // 触发结束条件
    if (track.size() == nums.length) {
        res.add(new LinkedList(track));
        return;
    }
    
    for (int i = 0; i < nums.length; i++) {
        // 排除不合法的选择
        if (track.contains(nums[i]))
            continue;
        // 做选择
        track.add(nums[i]);
        // 进入下一层决策树
        backtrack(nums, track);
        // 取消选择,返回上一层决策树
        track.removeLast();
    }
}
 

剪枝并且去重 

class Solution {
    List> res = new LinkedList<>();
    public List> combinationSum(int[] candidates, int target) {
        LinkedList track = new LinkedList<>();
        Arrays.sort(candidates);
        trackback(candidates,0,target,track);
        return res;
    }
    private void trackback(int[] candidates , int start ,int target ,LinkedList track){
        if(target == 0)
        {
            res.add(new LinkedList(track));
            return;
        }
        for(int i=start;i target)
                break;
            
            track.add(candidates[i]);
            trackback(candidates,i,target-candidates[i],track);
            track.removeLast();
        }
    }
}

 

你可能感兴趣的:(LeetCode)