Combination Sum II

本文介绍了一个寻找所有唯一组合的问题,这些组合中数字之和等于目标数。通过深度优先搜索算法,利用递归实现,确保每个元素只使用一次,并且不包含重复的组合。

Given an array num and a number target. Find all unique combinations in num where the numbers sum to target.

Example

Example 1:

Input: num = [7,1,2,5,1,6,10], target = 8
Output: [[1,1,6],[1,2,5],[1,7],[2,6]]

Example 2:

Input: num = [1,1,1], target = 2
Output: [[1,1]]
Explanation: The solution set must not contain duplicate combinations.

Notice

  1. Each number in num can only be used once in one combination.
  2. All numbers (including target) will be positive integers.
  3. Numbers in a combination a1, a2, … , ak must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak)
  4. Different combinations can be in any order.
  5. The solution set must not contain duplicate combinations.

思路:跟combination sum I 类似;注意区别在于: each element only used once. 所以,下个level循环,要从i+1开始,这样就避免了自己被重复使用。同时还要选代表去重复,1,1,7,第二个1不能选前面的1作为选项,因为两个11已经在第一个1的时候用过了;

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> lists = new ArrayList<List<Integer>>();
        List<Integer> list = new ArrayList<>();
        Arrays.sort(candidates);
        dfs(candidates, lists, list, target, 0, 0);
        return lists;
    }
    
    private void dfs(int[] candidates, List<List<Integer>> lists, List<Integer> list,
                    int target, int index, int cursum) {
        if(cursum > target) {
            return;
        }
        if(cursum == target) {
            lists.add(new ArrayList<Integer>(list));
            return;
        }
        for(int i = index; i < candidates.length; i++) {
            if(i > index && candidates[i] == candidates[i - 1]) {
                continue;
            }
            cursum += candidates[i];
            list.add(candidates[i]);
            dfs(candidates, lists, list, target, i + 1, cursum);
            list.remove(list.size() - 1);
            cursum -= candidates[i];
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值