回溯算法问题
通用模板:
void backtracking(参数) {
if (终止条件) { //一般到终止条件只要确保跟结果对的参数正确就行,不需要考虑其他参数,比如是否越界之类的。
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) { //一般这里就可以做剪枝
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
例子1:
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例: 输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]。
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> result; // 存放符合条件结果的集合
vector<int> path; // 用来存放符合条件结果
void backtracking(int n, int k, int startIndex) {
if (path.size() == k) {
result.push_back(path);
return;
}
for (int i = startIndex; i <= n; i++) {
path.push_back(i); // 处理节点
backtracking(n, k, i + 1); // 递归
path.pop_back(); // 回溯,撤销处理的节点
}
}
vector<vector<int>> combine(int targetSum, int k) {
result.clear(); // 可以不写
path.clear(); // 可以不写
backtracking(targetSum, k, 0, 1);
return result;
}
void printvv(vector<vector<int>> matrix) {
for (size_t i = 0; i < matrix.size(); ++i) {
for (size_t j = 0; j < matrix[i].size(); ++j) {
std::cout << matrix[i][j] << " ";
}
std::cout << std::endl;
}
}
int main() {
vector<vector<int>> matrix;
printvv(combine(4,2));
return 0;
}
例子2:
找出所有相加之和为 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]]
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> result; // 存放符合条件结果的集合
vector<int> path; // 用来存放符合条件结果
void backtracking(int targetSum, int k, int sum, int startIndex) {
if (path.size() == k) {
//std::cout << startIndex << ":" << k << std::endl;
if (targetSum == sum) {
result.push_back(path);
}
return;
}
for (int i = startIndex; i <= 9; i++) {
//std::cout << i << std::endl;
path.push_back(i);
backtracking(targetSum, k, sum + i, i + 1);
path.pop_back();
}
}
vector<vector<int>> combine(int targetSum, int k) {
result.clear(); // 可以不写
path.clear(); // 可以不写
backtracking(targetSum, k, 0, 1);
return result;
}
void printvv(vector<vector<int>> matrix) {
for (size_t i = 0; i < matrix.size(); ++i) {
for (size_t j = 0; j < matrix[i].size(); ++j) {
std::cout << matrix[i][j] << " ";
}
std::cout << std::endl;
}
}
int main() {
vector<vector<int>> matrix;
printvv(combine(22,6));
return 0;
}