N皇后问题
文中的图存在一个问题当N为3时是无解的,任何两个皇后处于一条斜线都不行,关于该点可参考N皇后动图
class Solution {
private:
vector<vector<string>> result;
// n 为输入的棋盘大小
// row 是当前递归到棋牌的第几行了 void backtracking(int n, int row, vector<string>& chessboard) { if (row == n) { result.push_back(chessboard); return; } for (int col = 0; col < n; col++) { //for循环横向走,递归纵向走,每个递归的纵向中又有横向 if (isValid(row, col, chessboard, n)) { // 验证合法就可以放 chessboard[row][col] = 'Q'; // 放置皇后 backtracking(n, row + 1, chessboard); //先考虑文中棋盘第一行col=0时候的纵向,同一列的情况下在不同row上放Q肯定不行,所以在检查列的时候只要有一个Q就false了
//所以不能在棋盘第一行col=0的情况下第二行第三行也col=0的递归下去,还要横向走就是递归中变化col chessboard[row][col] = '.'; // 回溯,撤销皇后
//这里回溯以文中的图中取1那一列递归完到取2开始为例,每一个for循环都会有撤销皇后,所以无论有多少次
//递归,每次递归完都会撤销皇后(子递归结束return后父递归就会执行撤销皇后),所以当最顶层的col=0这次for循环结束时,chessboard已经清零了,当然当顶层col=1时自然到了文中取1那一列了
//当然每次递归中的回撤就是回撤到上一层的状态了
} } } bool isValid(int row, int col, vector<string>& chessboard, int n) { int count = 0; // 检查列 for (int i = 0; i < row; i++) { // 这是一个剪枝 if (chessboard[i][col] == 'Q') { return false; } } // 检查 45度角是否有皇后 for (int i = row - 1, j = col - 1; i >=0 && j >= 0; i--, j--) { if (chessboard[i][j] == 'Q') { return false; } } // 检查 135度角是否有皇后 for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) { if (chessboard[i][j] == 'Q') { return false; } } return true; } public: vector<vector<string>> solveNQueens(int n) { result.clear(); std::vector<std::string> chessboard(n, std::string(n, '.')); backtracking(n, 0, chessboard); return result; } };

浙公网安备 33010602011771号