Combination Sum IV
Given an array of distinct integers nums and a target integer target, return the number of possible combinations that add up to target.
The answer is guaranteed to fit in a 32-bit integer.
Example 1:
Input: nums = [1, 2, 3], target = 4
Output: 7
Explanation:
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.
Example 2:
Input: nums = [9], target = 3
Output: 0
Constraints:
- 1 <= nums.length <= 200
- 1 <= nums[i] <= 1000
- All the elements of nums are unique
- 1 <= target <= 1000
Follow up: What if negative numbers are allowed in the given array? How does it change the problem? What limitation we need to add to the question to allow negative numbers?
今天这道算法题,要求输入一个整数数组nums,和一个整数target,要我们计算出由nums中的数求和计算得到target的方法有多少种。nums中的数字不重复,但是在求和的时候一个数字可以多次使用,而且不同的顺序也被认为是不同的方法。
这显然又是一道动态规划的题目,正好我最近想多练习练习动态规划算法呢,这道题来的正是时候。
我们先来分析一下,题目所求的是和为target的解法的个数,那么根据动态规划算法的常规思想,我们定义一个一维数组f(n),表示和为n的解法的个数。显然,f(0)=1,因为和为0的解法只有一种:不取任何数。然后根据动态规划的思想,对于所有的num<n,有f(n) += f(n-num)
根据这个思想,写出代码如下:
/**
* @author: LittleWang
* @date: 2021/4/24
* @description:
*/
public 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 num : nums) {
if(num <= i) {
f[i] += f[i-num];
}
}
}
return f[target];
}
}
只要理解了动态规划的思想,这个题总体来说难度不大,运行结果如下:
题目后面还给我们留了一道思考题
-
如果这道题目支持nums中含有负数会怎么样?它对题目造成了什么影响?如果要支持nums中有负数我们应该给题目加上什么限制?
如果nums中有负数,那么可能会出现和为target的结果无限多的情况,比如nums = [-1, -2, 3, 6], target = 5,其中-1-2+3=0,那么-1-2+3+(-1-2+3)+…的结果也都为0,就出现了结果为无穷大的情况。
况,比如nums = [-1, -2, 3, 6], target = 5,其中-1-2+3=0,那么-1-2+3+(-1-2+3)+…的结果也都为0,就出现了结果为无穷大的情况。
如果要支持负数的话,那么题目中就要加上运算次数限制,避免出现这种无限+0的情况。