zoukankan      html  css  js  c++  java
  • [LeetCode] 51. N-Queens N皇后问题

    The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

    Given an integer n, return all distinct solutions to the n-queens puzzle.

    Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

    Example:

    Input: 4
    Output: [
     [".Q..",  // Solution 1
      "...Q",
      "Q...",
      "..Q."],
    
     ["..Q.",  // Solution 2
      "Q...",
      "...Q",
      ".Q.."]
    ]
    Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.

    八皇后问题扩展到N皇后,经典的回溯算法题。

    解法:回溯Backtracking

    Java:

    public class Solution {
        public List<List<String>> solveNQueens(int n) {
            char[][] board = new char[n][n];
            for(int i = 0; i < n; i++)
                for(int j = 0; j < n; j++)
                    board[i][j] = '.';
            List<List<String>> res = new ArrayList<List<String>>();
            dfs(board, 0, res);
            return res;
        }
        
        private void dfs(char[][] board, int colIndex, List<List<String>> res) {
            if(colIndex == board.length) {
                res.add(construct(board));
                return;
            }
            
            for(int i = 0; i < board.length; i++) {
                if(validate(board, i, colIndex)) {
                    board[i][colIndex] = 'Q';
                    dfs(board, colIndex + 1, res);
                    board[i][colIndex] = '.';
                }
            }
        }
        
        private boolean validate(char[][] board, int x, int y) {
            for(int i = 0; i < board.length; i++) {
                for(int j = 0; j < y; j++) {
                    if(board[i][j] == 'Q' && (x + j == y + i || x + y == i + j || x == i))
                        return false;
                }
            }
            
            return true;
        }
        
        private List<String> construct(char[][] board) {
            List<String> res = new LinkedList<String>();
            for(int i = 0; i < board.length; i++) {
                String s = new String(board[i]);
                res.add(s);
            }
            return res;
        }
    }  

    Python:

    class Solution(object):
        def solveNQueens(self, n):
            """
            :type n: int
            :rtype: List[List[str]]
            """
            def dfs(curr, cols, main_diag, anti_diag, result):
                row, n = len(curr), len(cols)
                if row == n:
                    result.append(map(lambda x: '.'*x + "Q" + '.'*(n-x-1), curr))
                    return
                for i in xrange(n):
                    if cols[i] or main_diag[row+i] or anti_diag[row-i+n]:
                        continue
                    cols[i] = main_diag[row+i] = anti_diag[row-i+n] = True
                    curr.append(i)
                    dfs(curr, cols, main_diag, anti_diag, result)
                    curr.pop()
                    cols[i] = main_diag[row+i] = anti_diag[row-i+n] = False
    
            result = []
            cols, main_diag, anti_diag = [False]*n, [False]*(2*n), [False]*(2*n)
            dfs([], cols, main_diag, anti_diag, result)
            return result
    

    Python:

    # For any point (x,y), if we want the new point (p,q) don't share the same row, column, or diagonal.
    # then there must have ```p+q != x+y``` and ```p-q!= x-y```
    # the former focus on eliminate 'left bottom right top' diagonal;
    # the latter focus on eliminate 'left top right bottom' diagonal
    
    # - col_per_row: the list of column index per row
    # - cur_row:current row we are seraching for valid column
    # - xy_diff:the list of x-y
    # - xy_sum:the list of x+y
    class Solution2(object):
        def solveNQueens(self, n):
            """
            :type n: int
            :rtype: List[List[str]]
            """
            def dfs(col_per_row, xy_diff, xy_sum):
                cur_row = len(col_per_row)
                if cur_row == n:
                    ress.append(col_per_row)
                for col in range(n):
                    if col not in col_per_row and cur_row-col not in xy_diff and cur_row+col not in xy_sum:
                        dfs(col_per_row+[col], xy_diff+[cur_row-col], xy_sum+[cur_row+col])
            ress = []
            dfs([], [], [])
            return [['.'*i + 'Q' + '.'*(n-i-1) for i in res] for res in ress]  

    C++:

    class Solution {
    public:
        vector<vector<string> > solveNQueens(int n) {
            vector<vector<string> > res;
            vector<int> pos(n, -1);
            solveNQueensDFS(pos, 0, res);
            return res;
        }
        void solveNQueensDFS(vector<int> &pos, int row, vector<vector<string> > &res) {
            int n = pos.size();
            if (row == n) {
                vector<string> out(n, string(n, '.'));
                for (int i = 0; i < n; ++i) {
                    out[i][pos[i]] = 'Q';
                }
                res.push_back(out);
            } else {
                for (int col = 0; col < n; ++col) {
                    if (isValid(pos, row ,col)) {
                        pos[row] = col;
                        solveNQueensDFS(pos, row + 1, res);
                        pos[row] = -1;
                    }
                }
            }
        }
        bool isValid(vector<int> &pos, int row, int col) {
            for (int i = 0; i < row; ++i) {
                if (col == pos[i] || abs(row - i) == abs(col - pos[i])) {
                    return false;
                }
            }
            return true;
        }
    };
    

      

    类似题目:

    [LeetCode] 52. N-Queens II N皇后问题 II

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    表格排序插件datatables
    dropzone手动上传
    上传文件插件dropzone的实例
    table加载慢
    利用touchslide实现tab滑动切换
    Qt之事件处理机制
    Qt容器组件(二)之QWidgetStack、QMdiArea、QDockWidget
    ActiveMQ之ActiveMQ-CPP安装及测试
    Qt容器组件(一)之QGroupBox、QScrollArea、QToolBox、QTabWidget
    Qt属性系统(Qt Property System)
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9684713.html
Copyright © 2011-2022 走看看