leetcode日记 Combination sum IV

时间:2023-01-12 09:35:52

题目:

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.

一开始最直接的思路就是递归:拿给定的例子来说就是nums=[1,2,3] target=4 相当于,那么遍历nums,每次递归调用时将target-nums[i]作为参数传入下一层,这样就可以找到所有的组合,然后返回结果的个数即可。但是这样的尝试却TLE了,分析发现确实如此,即使nums中数目不多,只要target一大,那么递归的层数就会过多,这样一来极大的增加了时间复杂度。

随后便再想是不是能用DP来进行求解,从这个角度来看的话,这个问题就特别想斐波那契数列的DP求法,题目要求求得是不同排列的数目,那么很容易会发现,每一个数所得的排列数目都和之前的排列数目有关,和刚才的递归想法一致,只不过我们关注的是排列的数目而不是排列本身,target=4所得的排列数目按照[1,2,3]就可以分解为target=3,target=2,target=1的数目之和。如此一来,只要了解了nums就可以一步一步计算出target的排列数目。

java代码如下:

public int combinationSum4(int[] nums, int target) {
int result[]=new int[target+1];
result[0]=1;//如果target是nums中的一员,那么nums[0]就可以来表示这个数本身就可以当做一个排列
for (int i=1;i<target+1;i++)
for (int j=0;j<nums.length;j++){
if(i-nums[j]<0)
continue;
result[i]+=result[i-nums[j]];
}
return result[target];
}

python代码如下:

def combinationSum4(self, nums, target):

        """
:type nums: List[int]
:type target: int
:rtype: int
"""
result=[0]*(target+1)
result[0]=1
for i in xrange(0,target+1):
for j in xrange(0,len(nums)):
if i-nums[j]<0:
continue
result[i]+=result[i-nums[j]]
return result[target]

最后附上TLE 递归方法:(java)

public class CombinationSumIV {

    //递归复杂度太高,须其他方法
private static int count=0;
public int combinationSum4(int[] nums, int target) {
if (nums.length==0){
return 0;
}
ArrayList<Integer> temresult=new ArrayList<>();
for(int i:nums){
if (i > target){
continue;
}
else{
temresult.add(i);
deep(nums,target-i,temresult);
}
}
return count;
}
private void deep(int[] nums,int target,ArrayList<Integer> temresult){
if (target==0){
count++;
}
else {
for (int i:nums){
if (i>target){
continue;
}
else{
temresult.add(i);
deep(nums,target-i,temresult);
}
}
}
}
}