搜索回溯

简介

就是构建一颗搜索树,然后,基本上遍历所有的可能性然后找到结果,如果你想到暴力,那么你也应该想到递归回溯。

使用的技术手段

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("
");
    }
}
Hope is a good thing,maybe the best of things,and no good thing ever dies.----------- Andy Dufresne
原文地址:https://www.cnblogs.com/eat-too-much/p/14565357.html