[LeetCode] 39. Combination Sum 组合之和
Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.
The same repeated number may be chosen from candidates unlimited number of times.
Note:
- All numbers (including
target) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates =[2,3,6,7],target =7,
A solution set is:
[
[7],
[2,2,3]
]
Example 2:
Input: candidates = [2,3,5],target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
像这种结果要求返回所有符合要求解的题十有八九都是要利用到递归,而且解题的思路都大同小异,相类似的题目有 Path Sum II,Subsets II,Permutations,Permutations II,Combinations 等等,如果仔细研究这些题目发现都是一个套路,都是需要另写一个递归函数,这里我们新加入三个变量,start 记录当前的递归到的下标,out 为一个解,res 保存所有已经得到的解,每次调用新的递归函数时,此时的 target 要减去当前数组的的数,具体看代码如下:
解法一:
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> res;
vector<int> out;
combinationSumDFS(candidates, target, , out, res);
return res;
}
void combinationSumDFS(vector<int>& candidates, int target, int start, vector<int>& out, vector<vector<int>>& res) {
if (target < ) return;
if (target == ) {res.push_back(out); return;}
for (int i = start; i < candidates.size(); ++i) {
out.push_back(candidates[i]);
combinationSumDFS(candidates, target - candidates[i], i, out, res);
out.pop_back();
}
}
};
我们也可以不使用额外的函数,就在一个函数中完成递归,还是要先给数组排序,然后遍历,如果当前数字大于 target,说明肯定无法组成 target,由于排过序,之后的也无法组成 target,直接 break 掉。如果当前数字正好等于 target,则当前单个数字就是一个解,组成一个数组然后放到结果 res 中。然后将当前位置之后的数组取出来,调用递归函数,注意此时的 target 要减去当前的数字,然后遍历递归结果返回的二维数组,将当前数字加到每一个数组最前面,然后再将每个数组加入结果 res 即可,参见代码如下:
解法二:
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> res;
sort(candidates.begin(), candidates.end());
for (int i = ; i < candidates.size(); ++i) {
if (candidates[i] > target) break;
if (candidates[i] == target) {res.push_back({candidates[i]}); break;}
vector<int> vec = vector<int>(candidates.begin() + i, candidates.end());
vector<vector<int>> tmp = combinationSum(vec, target - candidates[i]);
for (auto a : tmp) {
a.insert(a.begin(), candidates[i]);
res.push_back(a);
}
}
return res;
}
};
我们也可以用迭代的解法来做,建立一个三维数组 dp,这里 dp[i] 表示目标数为 i+1 的所有解法集合。这里的i就从1遍历到 target 即可,对于每个i,都新建一个二维数组 cur,然后遍历 candidates 数组,如果遍历到的数字大于i,说明当前及之后的数字都无法组成i,直接 break 掉。否则如果相等,那么把当前数字自己组成一个数组,并且加到 cur 中。否则就遍历 dp[i - candidates[j] - 1] 中的所有数组,如果当前数字大于数组的首元素,则跳过,因为结果要求是要有序的。否则就将当前数字加入数组的开头,并且将数组放入 cur 之中即可,参见代码如下:
解法三:
class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<vector<int>>> dp;
sort(candidates.begin(), candidates.end());
for (int i = ; i <= target; ++i) {
vector<vector<int>> cur;
for (int j = ; j < candidates.size(); ++j) {
if (candidates[j] > i) break;
if (candidates[j] == i) {cur.push_back({candidates[j]}); break;}
for (auto a : dp[i - candidates[j] - ]) {
if (candidates[j] > a[]) continue;
a.insert(a.begin(), candidates[j]);
cur.push_back(a);
}
}
dp.push_back(cur);
}
return dp[target - ];
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/39
类似题目:
Letter Combinations of a Phone Number
参考资料:
https://leetcode.com/problems/combination-sum/
https://leetcode.com/problems/combination-sum/discuss/16825/Recursive-java-solution
https://leetcode.com/problems/combination-sum/discuss/16509/Iterative-Java-DP-solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 39. Combination Sum 组合之和的更多相关文章
- [leetcode]39. Combination Sum组合之和
Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), fin ...
- [array] leetcode - 39. Combination Sum - Medium
leetcode - 39. Combination Sum - Medium descrition Given a set of candidate numbers (C) (without dup ...
- leetcode 39. Combination Sum 、40. Combination Sum II 、216. Combination Sum III
39. Combination Sum 依旧与subsets问题相似,每次选择这个数是否参加到求和中 因为是可以重复的,所以每次递归还是在i上,如果不能重复,就可以变成i+1 class Soluti ...
- [LeetCode] Combination Sum 组合之和
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...
- LeetCode 39. Combination Sum (组合的和)
Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique c ...
- LeetCode 39 Combination Sum(满足求和等于target的所有组合)
题目链接: https://leetcode.com/problems/combination-sum/?tab=Description Problem: 给定数组并且给定一个target,求出所 ...
- LeetCode OJ:Combination Sum (组合之和)
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...
- 【LeetCode】Combination Sum(组合总和)
这道题是LeetCode里的第39道题. 题目描述: 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组 ...
- leetcode 39 Combination Sum --- java
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...
随机推荐
- SAP-简单的OALV演示练习
接上一篇传统ALV:https://www.cnblogs.com/BruceKing/p/11320165.html. 首先介绍下什么是ALV,在R/3 4.6C之前ALV全称为ABAP List ...
- ASP.NET MVC 实现简单的登录
1.创建一个控制器 如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; ...
- 基于OpenCV.Net投影法进行文本分块切割
假设有如下一张图,如何把其中的文本分块切割出来,比如“华普超市朝阳门店”.“2015-07-26”就是两个文本块. 做图像切割有很多种方法,本文描述一种最直观的投影检测法.先来看看什么是投影,简单来说 ...
- Flask--数据库连接池
目录 数据库连接池 pymsql链接数据库 数据库连接池版 数据库连接池 pymsql链接数据库 import pymysql conn = pymysql.connect(host='127.0.0 ...
- AES加解密异常java.security.InvalidKeyException: Illegal key size
AES加解密异常 Java后台AES解密,抛出异常如下:java.security.InvalidKeyException: Illegal key size Illegal key size or ...
- Vue内置组件[回顾]
1.动态组件 在某些场景,往往需要我们动态切换页面部分区域的视图,这个时候内置组件component就显得尤为重要. component接收一个名为is的属性,is的值应为父组件中注册过的组件的名称, ...
- 微信小程序自定义tabbar的实现
微信小程序自定义tabbar的实现 目的:当采用微信的自定义tabbar组件的时候,切换的时候会出现闪屏的效果:当使用微信默认的tabbar的时候,限制了tabbar的数量以及灵活配置. 方案:自己动 ...
- SAP 如何得到交货单上的序列号清单?
SAP 如何得到交货单上的序列号清单? 以内向交货单为例(外向交货单方法了类似)予以说明. 1)VL33N,在交货单显示界面, 但是没办法通过这个界面里导出序列号清单. 2),只能通过查表的方式导出序 ...
- loadView的原理
其他的小记: 1.控制器的view是怎么创建的 当外界第一次使用当前控制器的view时,会调用当前一个方法loadView,创建控制器的view: 控制器的view是懒加载的,什么时候使用,什么时候才 ...
- Django RestFramework(DRF)类视图
基础视图 1.基础函数视图(@api_view) DRF提供了一种函数基础视图来装饰Django的普通视图,我们可以使用request来接受请求和response响应.一个小例子: from rest ...