52. N-Queens II (H)

The n-queens puzzle is the problem of placing n queens on an n x 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 1:

Input: n = 4
Output: 2
Explanation: There are two distinct solutions to the 4-queens puzzle as shown.

Example 2:

Input: n = 1
Output: 1

Constraints:

  • 1 <= n <= 9

Solution:

Version 1:

不使用 boolean 数组来记录访问情况,直接暴力使用 for 循环来判断是否可以摆放在某个位置的写法。

java

class Solution {
    /**
     * Get all distinct N-Queen solutions
     * @param n: The number of queens
     * @return: All distinct solutions
     * For example, A string '...Q' shows a queen on forth position
     */
    public int totalNQueens(int n) {
        if (n <= 0) {
            return 0;
        }
        
        return search(new ArrayList<Integer>(), n);
    }
   
    private boolean isValid(List<Integer> cols, int colIndex) {
        int rowIndex = cols.size();
        for (int row = 0; row < cols.size(); row++) {
            int col = cols.get(row);
            if (col == colIndex || row + col == rowIndex + colIndex || 
                    row - col == rowIndex - colIndex) {
                return false;
            }
        }
        return true;
    }
    
    // search函数为搜索函数,n表示已经放置了n个皇后,cols 表示每个皇后所在的列
    private int search(List<Integer> cols, int n) {
        int rowIndex = cols.size();

        // 若已经放置了n个皇后表示出现了一种解法
        if (rowIndex == n) {
            return 1;
        }

        int sum = 0;
        // 枚举当前皇后放置的列,若不合法则跳过
        for (int colIndex = 0; colIndex < n; colIndex++) {
            if (!isValid(cols, colIndex)) {
                continue;
            }
            // 若合法则递归枚举下一行的皇后
            cols.add(colIndex);
            sum += search(cols, n);
            cols.remove(cols.size() - 1);
        }
        
        return sum;
    }
}

Version 2:

usedColumns[row]每次循环是直接改数值,不是累加,所以不需要回溯,加了usedColumns[row] = 0也不影响结果

public class Solution {
    public static int sum;
    public int totalNQueens(int n) {
        sum = 0;
        int[] usedColumns = new int[n];
        placeQueen(usedColumns, 0);
        return sum;
    }
    public void placeQueen(int[] usedColumns, int row) {
        int n = usedColumns.length;
        
        if (row == n) {
            sum ++;
            return;
        }
        
        for (int i = 0; i < n; i++) {
            if (isValid(usedColumns, row, i)) {
                usedColumns[row] = i;
                placeQueen(usedColumns, row + 1);
            }
        }
    }
    public boolean isValid(int[] usedColumns, int row, int col) {
        for (int i = 0; i < row; i++) {
            if (usedColumns[i] == col) {
                return false;
            }
            // 这里是判断对角线, 包含两种情况
            //row + col == i + usedColumns[i] 移项后就是row - i == usedColumns[i] - col 
            以及row - col == i - usedColumns[i] 移项后就是 row - i == col - usedColomns[i]
            if ((row - i) == Math.abs(col-usedColumns[i])) {
                return false;
            }
        }
        return true;
    }
}

Last updated

Was this helpful?