代码随想录——回溯 N皇后

image
image

思路

image

每次递归都遍历第0到n-1列,判断当前位置是否合法——确保不会和之前的皇后同列、同斜线(同行已经通过递归避免了)

那么核心就是

  1. 怎么判断是否合法
  2. 怎么返回答案

2反而比较重要,因为我一开始就设了个vector<int> queen,表示第i个皇后在第queen[i]列。但这在本题不好用,之后还得根据queen再生成string数组的答案。如果返回值是vector<vector<int>> 那么可以用。

1的基础方法简单

  1. 本题这种string保存的就查看同列/斜线是否有‘Q’
  2. 如果返回int数组的,就用坐标数学关系判断:同列则纵坐标相同,同斜线则 abs(横坐标差)=abs(纵坐标差)
    但以上方法是O(N)的复杂度,还可以优化为O(1)。本次暂时不写。

代码

下面是两种返回类型的答案

vector<vector<string>>

class Solution {
public:
    vector<vector<string>> result;
    void backtracking(vector<string>& queen,int n,int k){
        if(k == n){
            result.emplace_back(queen);
            return;
        }
        for(int col=0;col<n;col++){//遍历第k行第col列
            if(isValid(k,col,queen,n)){
                queen[k][col] = 'Q';
                backtracking(queen,n,k+1);
                queen[k][col] = '.';
            }
        }
    }
    bool isValid(int row,int col,vector<string>& queen,int n){
        //检查列
        for(int i=0;i<row;i++){
            if(queen[i][col] == 'Q')return false;
        }
        //检查左斜线
        for(int i=row-1,j=col+1;i>=0 && j<n;i--,j++){
            if(queen[i][j] == 'Q')return false;
        }
        //检查右斜线
        for(int i=row-1,j=col-1;i>=0 && j>=0;i--,j--){
            if(queen[i][j] == 'Q')return false;
        }
        return true;
    }

    vector<vector<string>> solveNQueens(int n) {
        // vector<int> queen(n);//第0个皇后(一定在第0行)在第queen[0]列
        result.clear();
        vector<string> queen(n,string(n,'.'));
        backtracking(queen,n,0);
        return result;

    }
};

vector<vector<int>>

class Solution {
public:
    vector<vector<int>> result;  // 存储所有的解,每个解是一个位置数组

    void backtracking(int n, int row, vector<int>& queen) {
        if (row == n) {  // 所有皇后都放置完成
            result.push_back(queen);  // 将当前解添加到结果中
            return;
        }

        for (int col = 0; col < n; col++) {
            if (isValid(row, col, queen)) {
                queen[row] = col;  // 将第row行的皇后放在col列
                backtracking(n, row + 1, queen);  // 递归放置下一个皇后
                queen[row] = -1;  // 回溯,撤销当前放置的皇后
            }
        }
    }

    bool isValid(int row, int col, const vector<int>& queen) {
        for (int i = 0; i < row; i++) {
            // 检查列冲突
            if (queen[i] == col) return false;
            // 检查斜线冲突
            if (abs(queen[i] - col) == abs(i - row)) return false;
        }
        return true;
    }

    vector<vector<int>> solveNQueens(int n) {
        result.clear();
        vector<int> queen(n, -1);  // 用来存储皇后的位置,-1表示尚未放置
        backtracking(n, 0, queen);
        return result;
    }
};
posted @ 2024-12-14 10:30  NeroMegumi  阅读(5)  评论(0编辑  收藏  举报