回溯算法

Posted xiao--ge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回溯算法相关的知识,希望对你有一定的参考价值。

回溯算法是一种尝试搜索求解的过程,当发现当前条件已经不满足求解的条件时就返回上一次的状态——回溯。

尝试别的路径,直至求出问题的解。有很多地方都用到了回溯的思想,算是一种“通用解”。

回溯法的一般步骤:

  1. 确定问题的解
  2. 确定边界
  3. 确定搜索规则
  4. 确定解所需要的条件

代码框架

bool Search(...)
{
    if(/*边界和解条件*/)
    {
        /*清除状态,回溯*/
        return false;
    }
    /*状态标记*/
    
    /*深度递归*/
    Search(...);
    
    /*得出解或者全部遍历完成后结束遍历*/
    return true;
}

N皇后

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

技术图片

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q‘ 和 ‘.‘ 分别代表了皇后和空位。

示例:

输入: 4
输出: [
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。

题目来源:https://leetcode-cn.com/problems/n-queens/

参考代码:

class Solution {
public:
    vector<vector<string>> solveNQueens(int n) {
        vector<string>map(n,string(n,‘.‘));
        swap(this->map,map);
        res.clear();
        this->n=n;
        dfs(0);
        return res;
    }
private:
    vector<vector<string>>res;
    vector<string>map;
    int n=0;
    bool isQueens(int y,int x){
        int base_11= (y-x)>0?y-x:0;
        int base_12= (x-y)>0?x-y:0;
        int base_21= (y+x)<n?y+x:n-1;
        int base_22= (y+x)<n?0:y+x-n+1;
        for(int i=0;i<n;++i){
            if(i!=x&&map[y][i]==‘Q‘)return false;
            if(i!=y&&map[i][x]==‘Q‘)return false;
            int list=base_11+i;
            int line=base_12+i;
            if(list>=0&&list<n&&line>=0&&line<n&&(list!=y||line!=x)){
                if(map[list][line]==‘Q‘)return false;
            }
            list=base_21-i;
            line=base_22+i;
            if(list>=0&&list<n&&line>=0&&line<n&&(list!=y||line!=x)){
                if(map[list][line]==‘Q‘)return false;
            }
        }
        return true;
    }
    void dfs(int z){
        if(z>=n){
            res.push_back(map);
            return;
        }
        for(int i=0;i<n;++i){
            map[z][i]=‘Q‘;
            if(isQueens(z,i))
                dfs(z+1);
            map[z][i]=‘.‘;
        }
    }
};

以上是关于回溯算法的主要内容,如果未能解决你的问题,请参考以下文章

回溯算法及题目

找到并回答后如何停止回溯算法?

回溯算法

回溯0--递归回溯算法框架

回溯算法

纠正用于回溯图着色算法的 Java 递归代码