算法初探LeetCode-组合总和 Ⅳ

113 阅读1分钟

LeetCode377:组合总和 Ⅳ

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

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

输入: 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)
请注意,顺序不同的序列被视作不同的组合。

示例 2:

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

提示:

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

思路分析

题目是要求得到所有的组合个数,看示例可以知道,事实上求的排序个数
1.dp[n]表示,target为n时,对应的组合个数 2.dp[i] += dp[i - nums[j]],这是求组合个数的通用公式,要求出来所有不同情况下之和 3.遍历顺序,由于是求排列个数,那么就要外层循环是target大小,内层循环是背包种类 4.初始化的话,还是只需要初始dp[0],因为它是所有的遍历结果的基础,其他的默认为0即可,因为都是正数

不限制放入元素的个数,限制求和的大小,是一个完全背包问题,准备好动手了 仔细一看,他可以由1,1,2,2,1,1两种形式的答案,这是一个排列问题,需要计算排列数 这时就需要先便利背包容量,再遍历物品,从前往后遍历,

算法代码

public int combinationSum4(int[] nums, int target) {
    int n = nums.length;
    int[] dp = new int[target + 1];
    dp[0] = 1;
    for (int i = 0; i <= target; i++) {
        for (int j = 0; j < n; j++) {
            if (i - nums[j] >= 0) {
                dp[i] += dp[i - nums[j]];
            }
        }
    }
    return dp[target];
}

结果详情

Snipaste_2023-04-11_22-56-33.png

算法复杂度

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)一起进步,一起成长!