216. 组合总和 III
找出所有相加之和为 n 的 k* 个数的组合**。***组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
- 所有数字都是正整数。
- 解集不能包含重复的组合。
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解题思路
这道题就是典型的回溯算法,确定条件然后直接套模板即可
问 答 需要遍历多少个? 从1开始,到 9 - k + 1
即可.因为如果大于这个值就不够数凑路径了,所以不用遍历递归终止条件 如果path的长度为K,且总和等于n就说明是我们需要的路径.加入结果即可.如果不是就直接返回 剪枝 如果当前path相加的总和比n大那么就不需要继续递归了.直接返回即可
个人写的一些模板总和,有兴趣可以看一下
✈✈✈✈算法模板✈✈✈✈
🕳回溯模板🕳
//用来存储结果
vector<vector<int>> res;
//递归加回溯算法,一般都是void类型.path用来记录路径,start记录当前开始的下标
//我比较喜欢path作为参数,这样path就相当于自然回溯了.不需要在path.pop_back();
//for找层序.递归找深度.
void backTracking(vector<int>path,int start,...)
{
//先加入路径
path.push_back( );
//递归终止条件
if(判断条件)
{
res.push_back(path);
return;
}
//num需要根据题意判断
for(int i = start + 1; i < num; i++)
{
backTracking(path,i,...)
}
}
代码:
class Solution {
private:
vector<vector<int>> res;
public:
void findWay(int k, int n, vector<int>path,int sum,int start)
{
//记录路径
path.push_back(start);
//记录路径总值,这样不用每次都计算路径总数
sum += start;
//如果总值比n大就直接返回
if (sum > n)
return;
//如果路径长度等于k
if (path.size() == k)
{
//判断是否总值等于n,是就说明是我们需要找的路径,加入结果
if(sum == n)
res.push_back(path);
//不是就直接返回
return;
}
//for找层序剩下的值,继续递归
for (int i = start + 1; i <= 9; i++)
{
findWay(k, n, path, sum,i);
}
}
vector<vector<int>> combinationSum3(int k, int n)
{
//定义一个空路径
vector<int> path;
//如果 i > 9 - k + 1 就说明已经凑不够数了,不需要遍历
for (int i = 1; i <= 9 - k + 1; i++)
{
findWay(k, n, path, 0, i);
}
return res;
}
};
总结:
回溯的典型题,看个人喜欢用全局的path还是参数path均可. 自己也写了一个回溯算法的模板.以后可以常看.