[LeetCode] 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] Combination Sum IV 组合之和之四的更多相关文章
- [LeetCode] 377. Combination Sum IV 组合之和之四
Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...
- [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 III 组合之和之三
Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...
- [LeetCode] Combination Sum II 组合之和之二
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...
- [Leetcode] combination sum ii 组合之和
Given a collection of candidate numbers ( C ) and a target number ( T), find all unique combinations ...
- 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 ...
随机推荐
- 【NLP】Tika 文本预处理:抽取各种格式文件内容
Tika常见格式文件抽取内容并做预处理 作者 白宁超 2016年3月30日18:57:08 摘要:本文主要针对自然语言处理(NLP)过程中,重要基础部分抽取文本内容的预处理.首先我们要意识到预处理的重 ...
- Java中的泛型 (上) - 基本概念和原理
本节我们主要来介绍泛型的基本概念和原理 后续章节我们会介绍各种容器类,容器类可以说是日常程序开发中天天用到的,没有容器类,难以想象能开发什么真正有用的程序.而容器类是基于泛型的,不理解泛型,我们就难以 ...
- 利用Python进行数据分析(11) pandas基础: 层次化索引
层次化索引 层次化索引指你能在一个数组上拥有多个索引,例如: 有点像Excel里的合并单元格对么? 根据索引选择数据子集 以外层索引的方式选择数据子集: 以内层索引的方式选择数据: 多重索引S ...
- 利用Python进行数据分析(13) pandas基础: 数据重塑/轴向旋转
重塑定义 重塑指的是将数据重新排列,也叫轴向旋转. DataFrame提供了两个方法: stack: 将数据的列“旋转”为行. unstack:将数据的行“旋转”为列. 例如: 处理堆叠格式 ...
- 通过三个DEMO学会SignalR的三种实现方式
一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...
- Maven环境配置
1.下载Maven: 下载地址:http://maven.apache.org/ 2..安装 Maven 如果需要使用到 Maven ,必须首先安装 Maven , Maven 的下载地址在 Apac ...
- ASP.NET Core服务器综述
原文地址:Servers overview for ASP.NET Core By Tom Dykstra, Steve Smith, Stephen Halter, and Chris Ross A ...
- lsof命令
学习资源https://linux.die.net/man/8/lsof lsof mean list open files 如果说linux中一切皆文件的话,那么lsof就是一盏照亮黑暗的文件系统的 ...
- querystring模块
querystring处理参数的小利器. 下面是querystring的四个方法. ①stringify:将一个参数对象序列化为一个字符串 eg: querystring.stringify({n ...
- C/C++内存泄漏及检测
参考 http://www.cnblogs.com/skynet/archive/2011/02/20/1959162.html