题目
给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。
题目数据保证答案符合 32 位整数范围。
示例
输入: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
解题示例:
说明:以下为宫水三叶的解题思路,目前本人能力优先,只是理解这种解题方法。
动态规划(降维优化)
我们知道「完全背包」可以通过取消物品维度来实现降维优化。
本题也可以使用相同手段:定义 f[i] 为凑成总和为 i 的方案数是多少。
由于 nums 的数都是正整数,因此我们有显然的初始化条件 f[0]=1(代表什么都不选,凑成总和为 0 的方案数为 1),同时最终答案为 f[target]。
不失一般性的考虑 f[i] 该如何转移,由于每个数值可以被选择无限次,因此在计算任意总和时,我们保证 nums 中的每一位都会被考虑到即可(即确保对组合总和 target 的遍历在外,对数组 nums 的遍历在内)。
class Solution {
public int combinationSum4(int[] nums, int target) {
int[] f = new int[target+1];
f[0] = 1;
for(int i = 1; i <= target; i++) {
for(int u : nums){
if (i>=u) f[i] += f[i-u];
}
}
return f[target];
}
}
此博客只作为个人笔记,若有侵权,联系删除。
end