算法: 求和377. Combination Sum IV

Posted AI架构师易筋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法: 求和377. Combination Sum IV相关的知识,希望对你有一定的参考价值。

377. Combination Sum IV

Given an array of distinct integers nums and a target integer target, return the number of possible combinations that add up to target.

The test cases are generated so that the answer can fit in a 32-bit integer.

Example 1:

Input: nums = [1,2,3], target = 4
Output: 7
Explanation:
The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

Note that different sequences are counted as different combinations.
Example 2:

Input: nums = [9], target = 3
Output: 0

Constraints:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 1000
  • All the elements of nums are unique.
  • 1 <= target <= 1000

Follow up: What if negative numbers are allowed in the given array? How does it change the problem? What limitation we need to add to the question to allow negative numbers?

从下到上求解

说明:以问题中的示例为例,其中 nums 为 [1, 2, 3],目标为 4。以下是您如何自下而上构建解决方案的方法,首先是总和为 1,然后是数字您总共可以制作 2 种方法,依此类推,最多 4 种:

1 -> [1]
2 -> [1, 1], [2]
3 -> [1, 1, 1], [1, 2], [2, 1], [3]
4 -> [1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1]

由于我们只需要计数,而不是实际的组合,因此可以将其简化为以下 DP 算法:

前置步骤:将 DP 数组初始化为 nums 中的每个数字的 1(因为您可以通过仅使用该数字本身轻松地得出该总数),否则为 0。

DP = [0, 1, 1, 1, 0]

现在,对于通往目标的每个数字,调用该子目标t_sub。通过获取 nums 中的每个数字n并检查我们能够制作 t_sub - n 的方式,然后将 其添加到t_sub的 DP 条目,看看我们可以通过多少种方式制作t_sub。

第 1 步:

t_sub = 1
t_sub - 1 = 0 所以什么都不加
t_sub - 2 < 0 所以什么都不加
t_sub - 3 < 0 所以什么都不加
DP = [0, 1, 1, 1, 0]

第 2 步:

t_sub = 2
t_sub - 1 = 1 所以 DP[2] += DP[1] 现在是 2
t_sub - 2 = 0 所以什么都不加
t_sub - 3 < 0 所以什么都不加
DP = [0, 1, 2 , 1, 0]

第 3 步:

t_sub = 3
t_sub - 1 = 2 所以 DP[3] += DP[2] 现在是 3
t_sub - 2 = 1 所以 DP[3] += DP[1] 现在是 4
t_sub - 3 = 0 所以什么都不加
DP = [0, 1, 2, 4, 0]

第 4 步:

t_sub = 4
t_sub - 1 = 3 所以 DP[4] += DP[3] 现在是 4
t_sub - 2 = 2 所以 DP[4] += DP[2] 现在是 6
t_sub - 3 = 1 所以 DP[4] += DP[1] 现在是 7
DP = [0, 1, 2, 4, 7]

现在我们完成了,所以返回 DP[-1],这是当t_sub是目标时我们可以制作t_sub的方式数。

在我们构建dp时,对于i的每个值,我们将遍历数字数组 ( N ) 中的不同num ,并通过添加来更新每个 num ( dp[i+num] )可以到达的单元格的值当前单元格的结果(dp[i])。如果当前单元格没有值,那么我们可以继续而不需要遍历N。

我们需要将dp[0]的值设为1来表示共同起点的值,然后一旦迭代完成,我们就可以返回 dp[T]作为我们的最终答案。

在自顶向下和自底向上的 DP 解决方案中,时间复杂度为O(N * T),空间复杂度为O(T)。

class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        nums, combs = sorted(nums), [1] + [0] * (target)
        for i in range(target + 1):
            for num in nums:
                if num  > i: break
                if num == i: combs[i] += 1
                if num  < i: combs[i] += combs[i - num]
        return combs[target]
class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        dp = [0] * (target + 1)
        dp[0] = 1
        for i in range(1, target+1):
            for n in nums:
                if n <= i:
                    dp[i] += dp[i-n]
        return dp[-1]

参考

https://leetcode.com/problems/combination-sum-iv/discuss/294990/Python-DP-beats-97-speed-and-91-memory-(with-explanation)

以上是关于算法: 求和377. Combination Sum IV的主要内容,如果未能解决你的问题,请参考以下文章

377. Combination Sum IV

377. Combination Sum IV

377. Combination Sum IV

377. Combination Sum IV

377. Combination Sum IV

377. Combination Sum IV