51. N 皇后- 回溯算法

題目描述

回溯算法經典思路

  1. 尋找路徑。
  2. 根據路徑,每個節點做出選擇,繼續向下尋找。
  3. 撤銷選擇。

算法框架


result = []
def backtrack(路徑, 選擇列表):
    if 滿足結束條件:
        result.add(路徑)
        return

    for 選擇 in 選擇列表:
        做選擇
        backtrack(路徑, 選擇列表)
        撤銷選擇

回溯算法解決N皇后問題

/**
 * @description:
 * @author: lilang
 * @version:
 * @modified By:[email protected]
 */
public class ListSolution {


    //定義返回節點位置

    List<List<String>> solutions = new ArrayList<List<String>>();


    public List<List<String>> solveNQueens(int n) {

        // 初始化皇后棋盤 初始值設置爲‘.’
        char[][] board = new char[n][n];

        for (int i = 0; i < board.length; i++) {
            Arrays.fill(board[i], '.');
        }

        //對棋盤進行逐行遍歷,這也是題目中所說的路徑方向
        backtrack(board, 0);

        return solutions;
    }

    /**
     * 棋盤迴溯
     * @param board  動態賦值過的棋盤
     * @param row  遍歷的當前行數
     */

    void backtrack(char[][] board, int row) {

        /**
         *  說明已經可以終止循環,已經到達最後一行了
         *
         */
        if (row == board.length) {

            solutions.add(array2List(board));

            return;
        }

        /**
         * 對每一行的元素進行檢測
         */
        for (int col = 0; col < board[row].length; col++) {

            /**
             * 判斷是否滿足皇后要求
             */
            if (findIsValid(board, row, col)) {
                //如果滿足,選擇當前位置變爲皇后
                board[row][col] = 'Q';
                //向下繼續執行
                backtrack(board, row + 1);
                //撤銷當前選擇
                board[row][col] = '.';
            }
        }

    }

    private boolean findIsValid(char[][] board, int row, int col) {


        // 檢查列是否有皇后互相沖突
        for (int i = 0; i < row; i++) {
            if (board[i][col] == 'Q')
                return false;
        }
        // 檢查右上方是否有皇后互相沖突

        for (int i = row - 1, j = col + 1; i >= 0 && j < board.length; ) {

            if (board[i][j] == 'Q') {
                return false;
            }
            i--;
            j++;

        }
        // 檢查左上方是否有皇后互相沖突

        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; ) {

            if (board[i][j] == 'Q') {
                return false;
            }
            i--;
            j--;

        }

        return true;

    }

    private List<String> array2List(char[][] board) {
        List<String> res = new LinkedList<>();
        for (char[] i : board) {
            StringBuffer sb = new StringBuffer();
            for (char j : i) {
                sb.append(j);
            }
            res.add(sb.toString());
        }
        return res;
    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章