LeetCode0039-组合总和

LeetCode0039-组合总和

题目:

给定一个无重复元素的数组 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]
]
代码:
import java.util.*;

/**
 * 0039-组合总和
 * 给定一个无重复元素的数组 candidates 和一个目标数 target ,
 * 找出 candidates 中所有可以使数字和为 target 的组合。
 * <p>
 * candidates 中的数字可以无限制重复被选取。
 * <p>
 * 说明:
 * <p>
 * 所有数字(包括 target)都是正整数。
 * 解集不能包含重复的组合。
 * <p>
 * 示例 1:
 * 输入:candidates = [2,3,6,7], target = 7,
 * 所求解集为:
 * [
 * [7],
 * [2,2,3]
 * ]
 * <p>
 * 示例 2:
 * 输入:candidates = [2,3,5], target = 8,
 * 所求解集为:
 * [
 * [2,2,2,2],
 * [2,3,3],
 * [3,5]
 * ]
 * <p>
 * 提示:
 * <p>
 * 1 <= candidates.length <= 30
 * 1 <= candidates[i] <= 200
 * candidate 中的每个元素都是独一无二的。
 * 1 <= target <= 500
 */

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        // 保存结果
        List<List<Integer>> result = new ArrayList<>();
        // 获取输入数组的长度
        int length = candidates.length;
        // 排序是为了提前终止搜索(剪枝操作)
        Arrays.sort(candidates);
        // 深度优先,回溯方法
        dfs(candidates, length, target, 0, new ArrayDeque<>(), result);
        return result;
    }

    /**
     * 回溯法(深度优先)
     *
     * @param candidates 数组输入
     * @param length     输入数组的长度
     * @param residue    剩余数值
     * @param begin      本轮搜索的起点下标
     * @param path       从根节点到任意节点的路径
     * @param result     结果集
     */
    private void dfs(int[] candidates, int length, int residue, int begin, Deque<Integer> path, List<List<Integer>> result) {
        if (residue == 0) {
            // 由于path 全局只使用一份,到叶子节点的时候需要保存结果
            result.add((new ArrayList<>(path)));
            return;
        }
        for (int i = begin; i < length; i++) {
            // 在数组有序的前提下,进行剪枝操作
            // 由于数组是排序好的,当前i的位置不满足添加,则后序的也不可能满足条件
            if (residue - candidates[i] < 0) {
                break;
            }
            // 满足条件,将该数字添加进path中
            path.addLast(candidates[i]);
            // 继续调用回溯函数,同时不修改搜索的起点下标,是为了解决数字可以重复的问题
            dfs(candidates, length, residue - candidates[i], i, path, result);
            // 回退
            path.removeLast();
        }
    }
}

public class Study0039 {
    public static void main(String[] args) {
        List<List<Integer>> result = new Solution().combinationSum(new int[]{2, 3, 5}, 8);
        for (List<Integer> list : result) {
            for (Integer number : list) {
                System.out.print(number + "\t");
            }
            System.out.println();
        }
    }
}

结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值