mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2026-07-04 08:25:37 +00:00
Create 377. Combination Sum IV.md
This commit is contained in:
parent
274da25ae0
commit
29d39fad7a
44
solutions/377. Combination Sum IV.md
Normal file
44
solutions/377. Combination Sum IV.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# [377. Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/)
|
||||||
|
|
||||||
|
# 思路
|
||||||
|
|
||||||
|
给定一个元素各不相同的数组和一个整数target,从数组从选取(可重复选)若干个数使和为target,问有多少种选法,注意一个排列就算一种选法,例如[1,2]和[2,1]是两种选法。
|
||||||
|
|
||||||
|
由于要求选法数,所以很容易想到用动态规划来求解,设
|
||||||
|
```
|
||||||
|
dp[i]表示target为i时的选法数(初始为0), dp[0] = 1
|
||||||
|
```
|
||||||
|
即dp[target]为所求。
|
||||||
|
|
||||||
|
转态转移方程也很简单,就是每次都遍历一遍给定的数组nums然后不断累加:
|
||||||
|
```
|
||||||
|
for all num in nums:
|
||||||
|
dp[i] += dp[i - num];
|
||||||
|
```
|
||||||
|
|
||||||
|
所以时间复杂度为O(n*target),空间复杂度为O(target)。
|
||||||
|
|
||||||
|
> 注意此题每个排列就算一种选法,例如[1,2]和[2,1]是两种选法,如果只算一次话那就是一个完全背包问题,可参考[我的博客-动态规划之背包问题系列](https://tangshusen.me/2019/11/24/knapsack-problem/)。
|
||||||
|
|
||||||
|
# C++
|
||||||
|
``` C++
|
||||||
|
class Solution {
|
||||||
|
public:
|
||||||
|
int combinationSum4(vector<int>& nums, int target) {
|
||||||
|
int n = nums.size();
|
||||||
|
vector<int>dp(target+1, 0);
|
||||||
|
dp[0] = 1;
|
||||||
|
for(int i = 1; i <= target; i++){
|
||||||
|
for(int &num: nums){
|
||||||
|
if(i >= num){
|
||||||
|
// 防止超过INT_MAX溢出
|
||||||
|
if(dp[i] <= INT_MAX - dp[i - num])
|
||||||
|
dp[i] += dp[i - num];
|
||||||
|
else dp[i] = INT_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[target];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue
Block a user