1. 程式人生 > 其它 >【LeetCode】51.N皇后

【LeetCode】51.N皇后

n皇后問題 研究的是如何將 n個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。

給你一個整數 n ,返回所有不同的n皇后問題 的解決方案。

每一種解法包含一個不同的n 皇后問題 的棋子放置方案,該方案中 'Q' 和 '.' 分別代表了皇后和空位。

輸入:n = 4
輸出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解釋:如上圖所示,4 皇后問題存在兩個不同的解法。

演算法1(DFS)

時間複雜度:\(O(n^{n+1})\)
套用回溯演算法框架即可,遍歷N叉樹。由於沒有重疊子問題,所以時間複雜度比較高,無法進行有效的優化。

  • 路徑:board 中小於 row 的那些行都已經成功放置了皇后
  • 選擇列表:第 row 行的所有列都是放置皇后的選擇
  • 結束條件:row 超過 board 的最後一行
class Solution {
public:
    vector<vector<string>> res;

    vector<vector<string>> solveNQueens(int n) {
        //初始化棋盤資訊
        vector<string> board(n, string(n, '.'));
        //遍歷n叉樹
        backtrack(board, 0); 
        return res;
    }

    void backtrack(vector<string>& board, int row) {
        //觸發結束條件
        if (row == board.size()) {
            res.push_back(board);
            return;
        }

        int n = board.size();
        for (int col = 0; col < n; col ++ ) {
            //排除非法選項
            if (!isValid(board, row, col))
                continue;

            board[row][col] = 'Q';
            backtrack(board, row + 1);
            board[row][col] = '.';
        }
    }

    bool isValid(vector<string>& board, int row, int col) {
        int n = board.size();

        //判斷當前列是否有衝突
        for (int i = 0; i < n; i ++ )
            if (board[i][col] == 'Q') return false;

        //判斷左上方是否有衝突
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i --, j -- )
            if (board[i][j] == 'Q') return false;

        //判斷右上方是否有衝突
        for (int i = row - 1, j = col + 1; i >= 0 && j < n; i --, j ++ )
            if (board[i][j] == 'Q') return false;

        return true;
    }
};