39.组合总和

  1. 组合总和
    给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。39.组合总和_第1张图片

class Solution {
    // 主函数,用于求解组合之和
    public List> combinationSum(int[] candidates, int target) {
        List> res = new ArrayList<>(); // 用于存放最终结果的列表
        Arrays.sort(candidates); // 对输入数组进行排序,便于后续处理
        // 调用回溯函数,寻找符合条件的组合
        //调用回溯函数backtracking,寻找符合条件的组合。传递结果列表res、空路径path、排序后的candidates、目标值target、当前组合的和sum(初始为0)以及开始遍历的索引idx(初始为0)
        backtracking(res, new ArrayList<>(), candidates, target, 0, 0);
        return res; // 返回结果列表
    }

    // 回溯函数
    public void backtracking(List> res, List path, int[] candidates, int target, int sum, int idx) {
        // 当前组合的和等于目标值时
        if (sum == target) {
            res.add(new ArrayList<>(path)); // 将当前组合添加到结果列表中
            return; // 结束当前递归
        }

        // 遍历候选数字,从 idx 开始
        for (int i = idx; i < candidates.length; i++) {
            // 当前组合的和加上当前候选数字大于目标值时,结束循环(因为后续的候选数字更大,组合的和会更大)
            if (sum + candidates[i] > target) break;
            path.add(candidates[i]); // 将当前候选数字添加到组合中
            // 递归调用回溯函数,继续寻找符合条件的组合
            //递归调用回溯函数backtracking,继续寻找符合条件的组合。传入的参数与上一次调用类似,但要更新当前组合的和(sum加上当前候选数字)以及遍历的起始索引(使用当前遍历的索引i,因为每个数字可以使用多次)
            backtracking(res, path, candidates, target, sum + candidates[i], i);
            path.remove(path.size() - 1); // 回溯,移除组合中最后添加的数字,尝试其他可能的组合
        }
    }
}

回溯函数通过这些参数的传递和更新,能够实现以下功能:

在递归过程中共享和更新结果列表res,将找到的有效组合添加到结果列表中。

跟踪当前正在构建的组合path,以便在递归过程中尝试添加和移除候选数字。

检查当前组合的和sum是否已经达到或超过目标值target。如果达到目标值,则将当前组合添加到结果列表;如果超过目标值,则终止当前分支的遍历。

根据开始遍历的索引idx,避免在构建组合时重复使用已经考虑过的较小索引。这有助于避免找到重复的组合,并允许多次使用相同数字。

通过这些参数的逻辑,回溯函数能够在递归过程中有效地查找和为目标值的组合。最后,主函数combinationSum返回结果列表res,其中包含所有符合条件的组合。

你可能感兴趣的:(算法,java,leetcode)