leetcode 51. N皇后 回溯法求解(c++版本)

题目描述

在这里插入图片描述
简单来说就给一个N*N的棋盘 棋盘上的每一列每一行以及每一个对角不能出现两个皇后
因此明确以下几点

  • 要找出所有可能的解法
  • 也是采用回溯法进行求解(具体在下面进行详解)

用下面一张示例图来说明回溯法的思路
在这里插入图片描述
说白了就是进行搜索, 每行进行搜索 行内再进行列搜索(每行的搜索用递归控制,行内每列的搜索用for循环进行控制) 那么当前位置符合我们的要求(行列对角线无其他皇后)将皇后放入
剩下的就是回溯法的正常流程了
那么递归函数的参数是什么呢,首先必须有在哪一行即行号,棋盘大小n也必须有,还有最重要的就是我们的棋盘(在主函数里人为构造)
还有一点就是判断当前位置放入皇后是否合法的问题(在代码注释里)

  • 两个对角(45°和135°)

代码实现

class Solution {
private:
    vector<vector<string>> result;
    // row 代表行号
    void backtracking(int row, int n, vector<string>& chess_board)
    {	// 访问到最后一行即结束
        if(row == n)
        {
            result.push_back(chess_board);
            return;
        }
        for(int i=0; i<n; i++)
        {	// 行内列的遍历搜索 当前位置符合要求即插入
            if(isValid(i, row, chess_board, n))
            {
                chess_board[row][i] = 'Q';
                backtracking(row+1, n, chess_board);
                chess_board[row][i] = '.';  // 回溯
            }
        }
    }
    // 判断当前位置是否有效  col列号  row行号
    bool isValid(int col, int row, vector<string>& chess_board, int n)
    {
        // 列
        for(int i = 0; i<row; i++)
        {	// 列号确定   遍历该列的每一行 
            if(chess_board[i][col]=='Q')
            {
                return false;
            }
        }
        // 45°
        for(int i = row-1, j=col+1; i>=0 && j<n; i--, j++)
        {	// 45 °的对角线位置  重点是 i>=0 && j<n 这个条件并起来狠关键
            if(chess_board[i][j]=='Q')
            {
                return false;
            }
        }
        // 135
        for(int i = row-1, j = col-1; i>=0 && j>=0; i--, j--)
        {	
            if(chess_board[i][j]=='Q')
            {
                return false;
            }
        }
        return true;
    } 
public:
    vector<vector<string>> solveNQueens(int n) {
    	// 创建一个n*n的棋盘用.来填充
        std::vector<std::string> chess_board(n, std::string(n, '.'));
        backtracking(0, n, chess_board);
        return result;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值