力扣刷题笔记《动态规划篇》→ 377. 组合总和 Ⅳ

264 阅读1分钟

这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战

题目

给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。

题目数据保证答案符合 32 位整数范围。

示例

输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。

输入: nums = [9], target = 3
输出: 0

提示

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 1000
  • nums 中的所有元素 互不相同
  • 1 <= target <= 1000

解题思路

要计算组合的数量,那么我们就需要知道每一位元素能有多少个组合,再将其进行汇总得出组合的总和。

  1. 边界定义 dp[0] = 1(由于1 <= nums[i],所以只有当没选择任何元素时总和才为0)
  2. 问题细化,当target大于nums[i]时,那么当前的元素nums[i]则必须加上target - nums[i]才能组合成target,因此我们可以先从1开始,得出前面的组合数量,便于后续组合进行取值。

代码实现

class Solution {
    public int combinationSum4(int[] nums, int target) {
        // 初始化
        int[] dp = new int[target + 1];
        dp[0] = 1;
        
        // 从 1 开始,往 target 遍历
        for (int i = 1; i <= target; i++) {
            // 遍历 nums, 累计求和
            for (int num : nums) {
                if (num <= i) {
                    dp[i] += dp[i - num];
                }
            }
        }
        
        // 返回结果
        return dp[target];
    }
}

复杂度分析

  • 时间复杂度:O(MN)O(MN)
  • 空间复杂度:O(M)O(M)

最后

文章有写的不好的地方,请大佬们不吝赐教,错误是最能让人成长的,愿我与大佬间的距离逐渐缩短!

如果觉得文章对你有帮助,请 点赞、收藏、关注、评论 一键四连支持,你的支持就是我创作最大的动力!!!

题目出处: leetcode-cn.com/problems/co…