[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 ...
随机推荐
- 如何给gridControl动态的添加合计
for (int i = 0; i < this.dsHz.Tables[0].Columns.Count; i++) { if (dsHz.Tables[0].Columns[i].DataT ...
- sequelize-auto生成sequelize所有模型
sequelize是node最受欢迎的orm库,普遍使用 Promise. 意味着所有异步调用可以使用 ES2017 async/await 语法. 快速入门地址:https://github.com ...
- Greenplum集群或者Postgresql出现死锁肿么办?
1.Greenplum集群或者Postgresql出现死锁肿么办? 由于Postgresql和Greenplum集群这数据库知识很深的,没有仔细研究,遇到问题真的不知道肿么处理,我遇到死锁,是采取了暴 ...
- C#中窗口关闭时没有取消事件订阅导致事件重复执行的解决方法
场景 C#中委托与事件的使用-以Winform中跨窗体传值为例: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100150700 ...
- 将Windows网络适配器共享网络的ip:192.168.137.1 改为其他IP
修改注册表 方法1 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SharedAccess\Parameters 中的: ScopeAddr ...
- python接口上传图片和文件的方法
import requests def sendImg(img_path, img_name, img_type='image/jpeg'): """ :param im ...
- python调用时间装饰器检测函数运行时间
用一个装饰器,监控程序的运行时间 import time def count_time(func): def int_time(*args, **kwargs): start_time = time. ...
- FCC-学习笔记 Spinal Tap Case
FCC-学习笔记 Spinal Tap Case 1>最近在学习和练习FCC的题目.这个真的比较的好,推荐给大家. 2>中文版的地址:https://www.freecodecamp. ...
- 实施一套MES系统需要多少钱?
在制造业深耕的人都知道MES系统对于企业的重要性.MES生产执行系统是制造业生产现场透明化管理的最佳解决方案,制造业工厂通过实施MES系统可以解决生产计划.排产调度.工艺管理.品质管理.现场数据采集和 ...
- 【AI测试】也许这有你想知道的人工智能 (AI) 测试--开篇
人工智能测试 什么是人工智能,人工智能是怎么测试的.可能是大家一开始最想了解的. 大家看图中关于人工智能的定义.通俗点来说呢,就是 让机器实现原来只有人类才能完成的任务:比如看懂照片,听懂说话,思考等 ...