题目描述
给你一个由 不同 整数组成的数组 nums
,和一个目标整数 target
。请你从 nums
中找出并返回总和为 target
的元素组合的个数。
题目数据保证答案符合 32
位整数范围。
样例1
输入: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
(动态规划) $\mathcal O(n \times target)$
- 状态表示:
f[i]
表示凑出i
的排列数,答案为f[target]
- 状态转移:对于任意一个小于
i
的数,即对于所有x
使得i >= x
,都有f[i] += f[i - x]
-
初始化:
f[0] = 1
表示凑出0
必须都不选,方案数为1
-
由于外层循环是遍历
1
到target
,内层循环是遍历数组的值,所以在计算f[i]
的时候,所有数组中的满足x <= i
的x
都会被作为f[i]
的前置选项,即不同的顺序都会被考虑到 - 如果不用考虑顺序,转换为完全背包问题(调换循环的次序),参考LeetCode518.零钱兑换II
Java 代码
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 x: nums){
if(i >= x) f[i] += f[i - x];
}
}
return f[target];
}
}