简介
就是构建一颗搜索树,然后,基本上遍历所有的可能性然后找到结果,如果你想到暴力,那么你也应该想到递归回溯。
使用的技术手段
DFS, 递归, 回溯(说人话,就是在dfs的过程中,回退操作,进而对下一次的递归不造成影响)
leetcode
组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
#include <string.h>
using namespace std;
#define ll long long
#define mod (long long)(1e9+7)
class Solution39 {
public:
void dfs(vector<int> &candidates, int target, vector<vector<int>> &ans, vector<int>& combine, int idx) {
if(idx == candidates.size()) { // 如果走到的数组的末尾直接返回
return;
}
if(target == 0) { // 如果我们需要
ans.emplace_back(combine);
return;
}
// 直接跳过
dfs(candidates, target, ans, combine, idx + 1); // 一个数组对idx这个节点不进行选择,直接递归
// 选择当前数
if(target - candidates[idx] >= 0) {
combine.emplace_back(candidates[idx]); // 选择这个节点,然后进行递归
dfs(candidates, target - candidates[idx], ans, combine, idx);
combine.pop_back(); // 为什么要进行pop_back操作,清除上一步的操作,上一步选择了这个节点,pop_back()清除这个操作
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
vector<vector<int>> ans;
vector<int> combine;
dfs(candidates, target, ans, combine, 0);
return ans;
}
};
# 在递归回溯算法中最有名的解决方案应该就是对于8皇后的解决方案
# 参考链接
https://www.bilibili.com/video/BV1wJ411U7Gy?from=search&seid=2696729038749911359
# 附上代码
```C++
#include <iostream>
using namespace std;
int place[8]={0}; // 第n个皇后所占位置的列号
bool flag[8] = {1, 1, 1, 1, 1, 1, 1, 1};// 标志数组,表示第col列是否可占用,1表示不冲突
bool d1[15] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};// 表示上对角线是否可占
bool d2[15] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};// 表示下对角线是否可占
int number = 0; // 用于统计解的数量 八皇后共有92个解
void print();
void generate(int n);
int main() {
generate(0);
return 0;
}
void generate(int n) {
int col;
for(col=0; col<8; col++){
if(flag[col]&& d1[n-col+7] && d2[n+col]) {// 判断位置是否冲突
place[n] = col;// 在n行col列摆放皇后
flag[col] = false; // 宣布占领第col列
d1[n-col+7] = false; // 宣布占领两个对角线
d2[n+col] = false;
if(n < 7) {
generate(n+1);
}else{
print(); // N==7, 皇后都放完了,打印结果
}
// 回溯:考虑其他的可行方案
flag[col] = true;
d1[n - col + 7] = true;
d2[n + col] = true;
}
}
}
void print() {
int col, i, j;
number++;
printf("No. %d
", number);
int table[8][8] = {0};
for(i = 0; i<8; i++) {
table[i][place[i]] = 1;
}
for(i = 0; i < 8 ; i++) {
for(j = 0; j < 8; j ++) {
printf("%d ", table[j][i]);
}
printf("
");
}
}