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

    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 the number of distinct solutions to the n-queens puzzle.

    Example:

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

    51. N-Queens N 的变形,这道题只需要给出不同解法的数量,比51题要简单一些。

    解法:回溯Backtracking

    Java:

    /**
     * don't need to actually place the queen,
     * instead, for each row, try to place without violation on
     * col/ diagonal1/ diagnol2.
     * trick: to detect whether 2 positions sit on the same diagnol:
     * if delta(col, row) equals, same diagnol1;
     * if sum(col, row) equals, same diagnal2.
     */
    private final Set<Integer> occupiedCols = new HashSet<Integer>();
    private final Set<Integer> occupiedDiag1s = new HashSet<Integer>();
    private final Set<Integer> occupiedDiag2s = new HashSet<Integer>();
    public int totalNQueens(int n) {
        return totalNQueensHelper(0, 0, n);
    }
    
    private int totalNQueensHelper(int row, int count, int n) {
        for (int col = 0; col < n; col++) {
            if (occupiedCols.contains(col))
                continue;
            int diag1 = row - col;
            if (occupiedDiag1s.contains(diag1))
                continue;
            int diag2 = row + col;
            if (occupiedDiag2s.contains(diag2))
                continue;
            // we can now place a queen here
            if (row == n-1)
                count++;
            else {
                occupiedCols.add(col);
                occupiedDiag1s.add(diag1);
                occupiedDiag2s.add(diag2);
                count = totalNQueensHelper(row+1, count, n);
                // recover
                occupiedCols.remove(col);
                occupiedDiag1s.remove(diag1);
                occupiedDiag2s.remove(diag2);
            }
        }
        
        return count;
    } 

    Python:

    # quick solution for checking if it is diagonally legal
    class Solution:
        # @return an integer
        def totalNQueens(self, n):
            self.cols = [False] * n
            self.main_diag = [False] * (2 * n)
            self.anti_diag = [False] * (2 * n)
            return self.totalNQueensRecu([], 0, n)
    
        def totalNQueensRecu(self, solution, row, n):
            if row == n:
                return 1
            result = 0
            for i in xrange(n):
                if not self.cols[i] and not self.main_diag[row + i] and not self.anti_diag[row - i + n]:
                    self.cols[i] = self.main_diag[row + i] = self.anti_diag[row - i + n] = True
                    result += self.totalNQueensRecu(solution + [i], row + 1, n)
                    self.cols[i] = self.main_diag[row + i] = self.anti_diag[row - i + n] = False
            return result
    

    Python:

    # slower solution
    class Solution:
        # @return an integer
        def totalNQueens(self, n):
            return self.totalNQueensRecu([], 0, n)
    
        def totalNQueensRecu(self, solution, row, n):
            if row == n:
                return 1
            result = 0
            for i in xrange(n):
                if i not in solution and reduce(lambda acc, j: abs(row - j) != abs(i - solution[j]) and acc, xrange(len(solution)), True):
                    result += self.totalNQueensRecu(solution + [i], row + 1, n)
            return result 

    C++:

    class Solution {
    public:
        int totalNQueens(int n) {
            int res = 0;
            vector<int> pos(n, -1);
            totalNQueensDFS(pos, 0, res);
            return res;
        }
        void totalNQueensDFS(vector<int> &pos, int row, int &res) {
            int n = pos.size();
            if (row == n) ++res;
            else {
                for (int col = 0; col < n; ++col) {
                    if (isValid(pos, row, col)) {
                        pos[row] = col;
                        totalNQueensDFS(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] 51. N-Queens N皇后问题

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    AtCoder Beginner Contest 167
    AtCoder Beginner Contest 166
    AtCoder Beginner Contest 165
    AtCoder Beginner Contest 164
    AtCoder Beginner Contest 163
    AtCoder Beginner Contest 162
    AtCoder Beginner Contest 161
    AtCoder Beginner Contest 160
    AtCoder Beginner Contest 159
    自定义Mybatis自动生成代码规则
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9684753.html
Copyright © 2011-2022 走看看