跳转至

51. N DOUDOU

力扣链接(困难):https://leetcode.cn/problems/n-queens

报意思,本人对各类名称十分敏感,由于原题名实在太难听,故改变了题名!当然,由于本分类原中文翻译也太过于难听,故保留为 Backtracking!

按照 DOUDOU 棋盘的规则,DOUDOU 可以攻击与之处在同一行或同一列或同一斜线上的棋子。

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

给你一个整数 n ,返回所有不同的 N DOUDOU 问题 的解决方案。

每一种解法包含一个不同的 N DOUDOU 问题 的棋子放置方案,该方案中 'Q''.' 分别代表了 DOUDOU 和空位。

示例 1:

img

Text Only
1
2
3
输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

Text Only
输入:n = 1
输出:[["Q"]]

提示:

  • 1 <= n <= 9

个人题解

C++
class Solution {
public:
    vector<vector<string>> result;

    // n 代表棋盘大小
    // 行不用检查,因为在 backtracking 每一次 for 遍历过程中,会把上次放置 Q 的位置重置,不会放置连续的 Q
    bool isValid(int row, int col, vector<string> &board, int n) {
        // 检查当前列
        for(int i = 0; i < row; i++) {
            if(board[i][col] == 'Q') return false;
        }

        // 检查对角线 135 degree
        for(int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            if(board[i][j] == 'Q') return false;
        }
        // 检查对角线 45 degree
        for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
            if(board[i][j] == 'Q') return false;
        }

        return true;
    }

    // n 棋盘大小,row 当前遍历行数
    void backtracking(int n, int row, vector<string> &board) {
        if(row == n) {
            result.push_back(board);
            return;
        }

        for(int col = 0; col < n; col++) {
            if(!isValid(row, col, board, n)) continue;
            board[row][col] = 'Q';
            backtracking(n, row + 1, board);
            board[row][col] = '.';
        }
    }
    vector<vector<string>> solveNQueens(int n) {
        vector<string> board(n, string(n, '.'));
        backtracking(n, 0, board);
        return result;
    }
};