题目
给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。
示例:
nums = [1, 2, 3]
target = 4
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。
因此输出为 7。
解题思路
不像组合总和、组合总和 II、组合总和 III是回溯的题目了,用回溯发现回超时,看标签想到了dp
用dp[i]
来表示总和为i
的组合数,则转移方程:
d
p
[
i
]
=
∑
k
∈
n
u
m
s
d
p
[
i
−
k
]
,
i
−
k
>
0
dp[i] = \sum_{k \in nums}dp[i - k], \;\;i - k > 0
dp[i]=k∈nums∑dp[i−k],i−k>0
初始化dp[0] = 1
时间复杂度是
o
(
m
n
)
o(mn)
o(mn),其中n
是target
,m
是nums
的长度
代码
class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
dp = [1] + [0] * target
for i in range(1, target + 1):
for each_num in nums:
if i - each_num >= 0:
dp[i] += dp[i - each_num]
return dp[-1]
Or we could do recursive with memorization:
class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
memo = {0: 1}
def helper(target: int) -> int:
if target in memo:
return memo[target]
res = 0
for i in range(len(nums)):
if target - nums[i] < 0:
continue
res += helper(target - nums[i])
memo[target] = res
return memo[target]
return helper(target)