funccombinationSum4(nums []int, target int)int { n := target // dp的含义, dp[i][j]对于长度i的组合, 总和为j的方案数, 本题由于nums全部为正数, 因此i最大为target dp := make([][]int, n+1) for i:=range dp { dp[i] = make([]int, target+1) } dp[0][0]=1 ans := 0 for i:=1;i<=n;i++{ for j:=0;j<=target;j++{ for _, u := range nums { if j>=u { dp[i][j]+=dp[i-1][j-u] } } } // 对于不同长度的组合, 总和为target的方案, 我们累加 ans += dp[i][target] }
return ans }
数组降维, 减少空间复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
funccombinationSum4(nums []int, target int)int { n := target dp := make([]int, target+1) dp[0]=1 ans := 0 for i:=1;i<=n;i++{ for j:=target;j>=0;j--{ dp[j] = 0 for _, u := range nums { if j>=u { dp[j]+=dp[j-u] } } } ans += dp[target] }
return ans }
进一步减少时间复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
funccombinationSum4(nums []int, target int)int { // 这个解法类似于爬楼梯, 对于每个总和j而言, nums为每次攀爬的楼梯数 // 所以 dp[j] = sum of { dp[j-nums[i]] for each i belong to 0..len(nums) } dp := make([]int, target+1) dp[0]=1 for j:=1;j<=target;j++{ for _, u := range nums { if j>=u { dp[j]+=dp[j-u] } } }