leetcode刷题/每日一题 77. 组合

77. 组合

题意:

给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例 1:

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

示例 2:

输入:n = 1, k = 1
输出:[[1]]

解题思路:

这道题类型与求长度为K的路劲.所以利用利用递归,再加上回溯

递归结束条件 如果路径长度等于K,就可以添加进入结果并返回
单层递归 如果不是,就遍历从当前节点的值开始直到K,继续递归.直到满足结束条件
剪枝 当路劲长度在加上剩余的数还小于K时,就直接放回.因为不可能凑出来(剩下很多时间)
  • 到这里其实就可以完成了,这是回溯的经典用法
class Solution {
private:
    vector<vector<int>> res;
public:
void DPS(int n, int k, int begin, vector<int>path)
{
    //当路劲长度在加上剩余的数还小于K,直接返回
    if (path.size() + (n - begin + 1) < k) 
	{
		return;
	}
    
    //先加入路劲
	path.push_back(begin);
    //路劲长度等于K,加入结果并返回
	if (path.size() == k)
	{
		res.push_back(path);
		return;
	}
    
    //从当前节点到n,逐个递归
	for (int i = begin + 1; i <= n; i++)
	{
		DPS(n, k, i, path);
	}
	
}
    vector<vector<int>> combine(int n, int k) {
	if (k <= 0 || n < k) 
	{
		return res;
	}
    //存储路劲
	vector<int> cacth;
    //开始节点最大为 n - k + 1,并这个大的数不可能组成.
	for (int i = 1; i <= n - k + 1; i++)
	{
		DPS(n, k, i, cacth);
	}

    //返回结果
	return res;
    }
};

总结:

这道题其实做起来有点绕,因为需要用到回溯.我定义的path没有用它的引用,所以时隐性回溯.

你可能感兴趣的:(算法,leetcode,数据结构,c++,递归法)