【中等】力扣算法题解析LeetCode377:组合总和 Ⅳ

关注文末推广名片,即可免费获得本题测试源码

题目来源:LeetCode 377. 组合总和 Ⅳ

问题抽象: 给定一个 无重复元素 的整数数组 nums(元素值 ≥1)和一个目标整数 target≥0),要求计算所有 和为 target 的组合数量(元素可重复使用),满足以下核心需求:

  1. 组合规则定义

    • 组合中每个元素可从 nums无限次选取
    • 顺序不同的序列视为不同组合(如 (1,2)(2,1) 算两种);
    • 组合元素和必须 严格等于 target(无小数部分)。
  2. 计算约束

    • 时间复杂度 O(n × target)nnums 长度),空间复杂度 **O(target)`;
    • 需用 动态规划 避免回溯法指数级开销:
      • 定义 dp[i] 表示和为 i 的组合数;
      • 状态转移:dp[i] = sum(dp[i - num] for num in nums if i ≥ num)
      • 初始化 dp[0] = 1(空组合和为 0)。
  3. 边界处理

    • target=0 时返回 1(空组合);
    • nums 为空且 target>0 时返回 0
    • 特殊值验证:
      • nums=[1,2,3], target=4 → 输出 7(组合:(1,1,1,1), (2,2), (1,1,2)×3, (1,3)×2, (3,1)×2);
      • nums=[9], target=3 → 输出 0(无法组合);
    • 大数处理:
      • nums=[1], target=1000 → 输出 1(仅 10001 一种组合);
      • 结果值可能较大(但保证在 32 位整数范围内)。
  4. 排列特性

    • 因顺序敏感,本质是 排列问题(与顺序无关的组合总和问题区分);
    • 动态规划需 先遍历和 i1target),内层遍历数组元素(确保顺序差异被计数)。

输入:整数数组 nums(长度 ≥0),目标整数 target≥0)。
输出:满足条件的组合数量(整数值)。


解题思路

本题要求找出总和为 target 的元素组合个数(不同顺序视为不同组合)。这是一个典型的动态规划问题,关键点在于:

  1. 状态定义dp[i] 表示组成目标数 i 的组合数。
  2. 初始化dp[0] = 1(组成0只有一种方式,即空组合)。
  3. 状态转移:对于每个目标数 i,遍历数组 nums 中的每个元素 num,若 i >= num,则 dp[i] += dp[i - num]。这表示将 num 作为组合的最后一个元素时,组合数取决于剩余部分 i - num 的组合数。
  4. 优化:先对数组排序,内层循环中当 num > i 时提前终止(因为后续元素均大于 i),减少无效计算。
  5. 注意事项:题目保证答案在32位整数范围内,但中间状态可能溢出。由于最终结果在范围内,中间状态直接使用 int 即可。

代码实现(Java版)🔥点击下载源码

class Solution {
    public int combinationSum4(int[] nums, int target) {
        int[] dp = new int[target + 1]; // dp[i] 表示组成目标数 i 的组合数
        dp[0] = 1; // 初始化:目标数为0时只有空组合一种方式
        Arrays.sort(nums); // 排序数组,便于内层循环提前终止
        for (int i = 1; i <= target; i++) {
            for (int num : nums) {
                if (num > i) break; // 提前终止:当前数已大于目标数
                dp[i] += dp[i - num]; // 状态转移
            }
        }
        return dp[target];
    }
}

代码说明

  1. 初始化dp[0] = 1 表示目标数为0时只有空组合一种方式。
  2. 排序数组:先对 nums 排序,确保在内层循环中遇到大于当前目标数 i 的元素时提前终止,减少无效计算。
  3. 动态规划
    • 外层循环遍历目标数 i 从1到 target
    • 内层循环遍历排序后的数组元素 num
      • num > i,则后续元素均大于 i,直接终止内层循环。
      • 否则,状态转移:dp[i] += dp[i - num]
  4. 返回值dp[target] 即为组成目标数 target 的组合数。
  5. 复杂度:时间复杂度 O(n log n + target * n)(排序 + 动态规划),空间复杂度 O(target)。优化后的内层循环在数组元素较大时显著减少计算量。

提交详情(执行用时、内存消耗)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值