[LeetCode] 377. Combination Sum IV 组合之和之四
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.
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?
Credits:
Special thanks to @pbrother for adding this problem and creating all test cases.
这道题是组合之和系列的第四道,博主开始想当然的以为还是用递归来解,结果写出来发现 TLE 了,的确 OJ 给了一个 test case 为 [4,1,2] 32,这个结果是 39882198,用递归需要好几秒的运算时间,实在是不高效,估计这也是为啥只让返回一个总和,而不是返回所有情况,不然机子就爆了。而这道题的真正解法应该是用 DP 来做,解题思想有点像之前爬梯子的那道题 Climbing Stairs,这里需要一个一维数组 dp,其中 dp[i] 表示目标数为i的解的个数,然后从1遍历到 target,对于每一个数i,遍历 nums 数组,如果 i>=x, dp[i] += dp[i - x]。这个也很好理解,比如说对于 [1,2,3] 4,这个例子,当计算 dp[3] 的时候,3可以拆分为 1+x,而x即为 dp[2],3也可以拆分为 2+x,此时x为 dp[1],3同样可以拆为 3+x,此时x为 dp[0],把所有的情况加起来就是组成3的所有情况了,参见代码如下:
解法一:
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + );
dp[] = ;
for (int i = ; i <= target; ++i) {
for (auto a : nums) {
if (i >= a) dp[i] += dp[i - a];
}
}
return dp.back();
}
};
如果 target 远大于 nums 数组的个数的话,上面的算法可以做适当的优化,先给 nums 数组排个序,然后从1遍历到 target,对于i小于数组中的数字x时,直接 break 掉,因为后面的数更大,其余地方不变,参见代码如下:
解法二:
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + );
dp[] = ;
sort(nums.begin(), nums.end());
for (int i = ; i <= target; ++i) {
for (auto a : nums) {
if (i < a) break;
dp[i] += dp[i - a];
}
}
return dp.back();
}
};
我们也可以使用递归+记忆数组的形式,不过这里的记忆数组用的是一个 HashMap。在递归函数中,首先判断若 target 小于0,直接返回0,若 target 等于0,则返回1。若当前 target 已经在 memo 中存在了,直接返回 memo 中的值。然后遍历 nums 中的所有数字,对每个数字都调用递归,不过此时的 target 要换成 target-nums[i],然后将返回值累加到结果 res 中即可,参见代码如下:
解法三:
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
unordered_map<int, int> memo;
return helper(nums, target, memo);
}
int helper(vector<int>& nums, int target, unordered_map<int, int>& memo) {
if (target < ) return ;
if (target == ) return ;
if (memo.count(target)) return memo[target];
int res = , n = nums.size();
for (int i = ; i < n; ++i) {
res += helper(nums, target - nums[i], memo);
}
return memo[target] = res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/377
类似题目:
参考资料:
https://leetcode.com/problems/combination-sum-iv/
https://leetcode.com/problems/combination-sum-iv/discuss/85079/My-3ms-Java-DP-solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 377. Combination Sum IV 组合之和之四的更多相关文章
- [LeetCode] 377. Combination Sum IV 组合之和 IV
Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...
- [LeetCode] Combination Sum IV 组合之和之四
Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...
- 377 Combination Sum IV 组合之和 IV
Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...
- [LeetCode] 216. Combination Sum III 组合之和 III
Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...
- [leetcode]40. Combination Sum II组合之和之二
Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...
- [LeetCode] 40. Combination Sum II 组合之和 II
Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...
- [LeetCode] 40. Combination Sum II 组合之和之二
Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...
- Leetcode 377. Combination Sum IV
Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...
- [LeetCode] Combination Sum III 组合之和之三
Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...
随机推荐
- locally weighted regression - CS229
欠拟合和过拟合 看下方的三张图 第一幅拟合为了 y=θ0+θ1xy=θ0+θ1x 的一次函数 第二幅拟合为了y=θ0+θ1x+θ2x2y=θ0+θ1x+θ2x2 的二次函数 第三幅拟合为了 y=∑5j ...
- S-T-E-A-M Science Technology Engineering Art Mathematics 五种思维模式
S-T-E-A-M五个英文字母分别代表 Science 科学,Technology 技术,Engineering 工程,Art 艺术以及 Mathematics 数学.它们并不是简单地整合原来的分科体 ...
- 如何取消 SqlDataAdapter.Fill() 的执行(转载)
问 Scenario: We have a DataGridView which is attached to DataAdapter (datatable), we load the data in ...
- 读取txt文件内容,并按一定长度分页显示
private List<string> SaveContentUpload(FileUpload file) { List<string> list_content = ne ...
- XMind破解版,2019年8月好使
越来越多的公司用思维导图了,进行编写测试用例,以下为破解版,亲身实验才发 的 ,中国时间2019年8月5日 下载安装包: 链接:https://pan.baidu.com/s/1-ubJLPSEpH ...
- win10自动休眠解决方法
win10使用外接显示器时,总是过2分钟自动睡眠. 这是系统无人值守时睡眠时间的设定,默认是两分钟. 解决方法: 1.运行注册表管理器,win+r ,输入regedit.exe 2.定位到HKEY_L ...
- crontab运行python不生效,但是手动执行正常的问题和解决方案
crontab运行python不生效,但是手动执行正常的问题和解决方案 linux默认装的是python2.7,安装了其他版本后直接执行没问题,但在crontab里执行不了,需要使用全路径. 使用 w ...
- Qt ini文件
ini文件格式 节(section) 节用方括号括起来,单独占一行,例如: [section] 键(key) 键(key)又名属性(property),单独占一行用等号连接键名和键值,例如: name ...
- vue学习指南:第十一篇(详细) - Vue的 路由 第一篇 ( router )
一.路由的配置 路由 vue-router 1. 什么是路由? 路由相当于一个配置对象 路由:就是我们通过不同的url访问不同的内容,通过angular.js 可以实现多视图的单页,现在流行的单页面 ...
- os模块,sys模块,json和pickle模块,logging模块
目录 OS模块 sys模块 json和pickle模块 序列化和反序列化 json模块 pickle logging模块 OS模块 能与操作系统交互,控制文件 / 文件夹 # 创建文件夹 import ...