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 题目汇总

  • 相关阅读:
    对var和let作用域用闭包的特性做最好的解释
    Js函数作用域
    问题记录
    Git学习
    React-router BrowserRouter导致axios请求时会重复url中的某些字段
    leetcode python 032 识别最长合法括号
    leetcode python 030 Substring with Concatenation of All Words
    n阶楼梯,一次走1,2,3步,求多少种不同走法
    leetcode python 012 hard 合并k个有序链表
    leetcode python 011
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9684753.html
Copyright © 2011-2022 走看看