Leetcode39 - 组合之和

例题:

题目要求找出数组中可以使数字和等于目标数 target 的所有的不同组合,并以集合的形式返回,同一个数字可以被无限制地选取。

注意:                

分析:

假如现在有一个数组candidates = [2, 3, 6, 7],需要组合和为7(target = 7),我们可以先固定2,此时 target = 7 - 2 = 5, 还不够,要继续组合,继续从数组的开始(第一个元素2)进行组合,因为数组中的元素可以被重复选取。 再固定2,2, target = 3,固定2,2,2,target = 1,再固定2,2,2,2,此时 target = -1 < 0,不满足条件,要回溯到2,2,2。 接着和3,6,7组合(保不齐数组中有个元素1)。发现和其他元素组合都无解,然后回溯到2,2,紧接着和3组合,发现此时target = 0,找到一组解:2,2,3。当target < 0 时,表示和 溢出了,需要回溯。

图中蓝色的矩形表示有效解。矩形上面的数字代表还差几就能达到target。

我们可以发现,这棵树里存在很多不必要的递归,比如说取值为负数的都是不必要的。比如当栈中已经固定了2,2,2这三个数,此时target = 1,剩余的数 1 比2,3,6,7都要小,没有必要和它们组合了。可以减枝。当剩余的数 < 待组合的数,就没有必要继续递归了。

像这样:

怎么写代码:

当我们做求组合这类的题目时,参数一般都要带上start(遍历数组中的数字时,它的起点索引),为了避免组合中的重复。再带上一个栈,用来保存组合的元素。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class CombinationLeetcode39 {
    public static void main(String[] args) {
        List<List<Integer>> lists = combinationSum(new int[]{2, 3, 6, 7}, 7);
        for (List<Integer> list : lists) {
            System.out.println(list);
        }
    }

    public static List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> result = new ArrayList<>();
        dfs(0, target, candidates, new LinkedList<>(), result);
        return result;
    }

    public static void dfs(int start, int target, int[] candidates, LinkedList<Integer> stack, List<List<Integer>> result){
        if(target == 0){
            result.add(new ArrayList<>(stack));
            return;
        }

        for (int i = start; i < candidates.length; i++) {
            int candidate = candidates[i];

            if(target < candidate){
                continue;
            }

            stack.push(candidate);
            dfs(i, target - candidate, candidates, stack, result);
            stack.pop();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值