汇总-排列组合子集问题

起因还是昨天那个没能解决的问题,现在看来更确切地描述是:给一个包含n个元素的数组,返回长度为1-n的所有排列组合

可能更接近这道题力扣-77-组合

昨天复习过的力扣-46-全排列用的是回溯

模板

/*
* 排列组合回溯模板
* 这里以216-组合总和Ⅲ为例,其实就是77-组合多加了一个target判断
*/
class Solution {
public:
	// 保存返回结果的二维数组
	vector<vector<int>> res;
	// 用于存放每一个组合/序列的中间临时数组,写成类变量主要是因为
	// 1. 虽然整个递归过程是多路的,但是具体执行过程中是串行的,伴随着push、pop操作,完全可以复用
	// 2. 写成类变量而不是局部变量可以减少传参和创建&销毁的性能消耗
	vector<int> temp;
	vector<vector<int>> combinationSum3(int k, int n) {
		backTrack(k, n, 1);
		return res;
	}
	/*
	* 因为需要用到递归,原函数需要用来返回结果不可用,所以单独定义一个函数来做递归过程
	* cur表示当前递归过程开始选的数字(这里因为是直接从1-9选,所以把下标和元素值合二为一了,不然这里应该是下标)
	* 这么做是因为:不能重复选择,每次都从上一次选择的后面的元素选,一定不会重复
	*/
	void backTrack(int k, int target, int cur) {
		// 剪枝
		if (target < 0) return;
		// 出口条件
		if (temp.size() == k && target == 0) {
			res.push_back(temp);
			return;
		}
		for (int i = cur; i <= 9; i++) {
			temp.push_back(i);
			// 每次减去当前的选中值更新target
			backTrack(k, target - i, i + 1);
			// pop是为了不影响下一次for循环
			temp.pop_back();
		}
	}
};
posted @ 2022-12-09 10:35  YaosGHC  阅读(22)  评论(0)    收藏  举报