原题链接:https://leetcode-cn.com/problems/combination-sum-iv/
1、递归
一开始用递归做,写完就就对了,不过超时了,其实我没有很懂为何递归不会出现重复。
代码:
int combinationSum4(vector<int>& nums, int target) {
if(target==0) return 1;
int len=nums.size();
int count=0;
for(int i=0;i<len;i++){
if(target>=nums[i])
count+=combinationSum4(nums,target-nums[i]);
}
return count;
}
2、动态规划:
于是用动态规划
int combinationSum4(vector<int>& nums, int target) {
vector<unsigned long long> dp(target + 1, 0);
dp[0] = 1;
for (int i = 1; i <= target; ++i) {
for (auto &x : nums) {
if (x <= i) {
dp[i] += dp[i - x];
}
}
}
return dp[target];
}
go版本
const N = 1010
func combinationSum4(nums []int, target int) int {
var dp [N]int
n := len(nums)
dp[0] = 1
for i := 1; i <= target; i++ {
for j := 0; j < n; j++ {
if i >= nums[j] {
dp[i] += dp[i-nums[j]]
}
}
}
return dp[target]
}
关键是在于这张图(来源),就可以理解递归为何正确和动规为何这样写了
拿例子推一推就发现递归没有重复,而且动态规划就是自底向上实现了这个树,牛!这题很经典!