377. 组合总和 Ⅳ

Difficulty
Medium
Tags
DFS
回溯
动态规划
Star
给你一个由 不同 整数组成的数组 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
进阶:如果给定的数组中含有负数会发生什么?问题会产生何种变化?如果允许负数出现,需要向题目中添加哪些限制条件?
 
 
💡
因为本题目对于nums中元素的选取有先后顺序,所以每次找 组成i 的组合数,都要遍历一遍 nums. 这其实是一个简单的动态规划,当然也可以采用 记忆化搜索来做。

法1 回溯

思路
采用回溯法,来找(会超时)
题解
class Solution: def combinationSum4(self, nums: List[int], target: int) -> int: self.res = 0 self.dfs(sum_=0, nums=nums, target=target) return self.res def dfs(self, sum_, nums, start, target): if sum_ == target: self.res += 1 if sum_ > target: return for i in range(0, len(nums)): sum_ += nums[i] self.dfs(sum_, nums, target) sum_ -= nums[i]

法2 动态规划

思路
dp[i] 为所有物品 能组成 i 的组合个数。
理解为一个爬楼梯问题:nums数组中的值想象成一次可以攀爬的步数
题解
class Solution: def combinationSum4(self, nums: List[int], target: int) -> int: dp = [0 for _ in range(target+1)] dp[0] = 1 # dp[i] 为所有物品 组成 i 的组合个数 for j in range(1, target+1): for num in nums: if j-num >=0: dp[j] += dp[j-num] return dp[target]