题目:
Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.
Example:
nums = [1, 2, 3]
target = 4
The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
Note that different sequences are counted as different combinations.
Therefore the output is 7.
题意:
给定一个数组,数组中的每一个数都不出现重复而且都是正数,再给定一个target数,要求数组中的所有数字组成的组合的和为target,那么输出所有的组合个数。当然组合个数是可以出现出现重复的。
题解:
此题如果一开始用DFS来做,那么和之前的Combination Sum类似,然后我们再应用数组的全排列的思想去求所有的个数,这种方案在此题中会超时。因为用递归+回溯的方法其实是用穷举的方式对所有的数字进行遍历,那必然会出现超时的情况发生,所以我们考虑用动态规划,因为根据此题的信息,比如1,3和3,1就是两种不同的情况了,所以我们考虑动态规划的时候,就会相应的对这两种情况进行分别考虑。那该如何用动态规划来解题呢?我们仔细分析,用一个额外的数组来保存每一个和结果的情况。比如用num数组来保存。因为要保证同一种情况下,不同数字的不同排列为不同种情况,那么就是动态规划比较方便的一种情况。
代码:
public class combinationSum4
{
public static int combinationSum4(int[] nums,int target)
{
if(target == 0)
return 1;
int[] mark = new int[target + 1]; //mark数组表示当此位置后,一共有多少种情况
mark[0] = 1;
for(int i = 1; i <= target; i++) //外层循环
{
for(int j = 0; j < nums.length; j++) //内层循环
{
if(i >= nums[j])
{
mark[i] += mark[i - nums[j]]; //将之前的每一个数字的情况加上某一个数字,当作一种新的情况
}
}
}
return mark[target];
}
}
其实这种类似的全排列问题都可以用类似这种动态规划的思路来解题。