51 N-Queens

51. N-Queens

经典的题目……很有趣

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.

For example, There exist two distinct solutions to the 4-queens puzzle:

[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]

分析& 代码

参考该博客

首先说一下判断一个格子是不是能放,行列+两侧斜角比较非常笨重,可以用一个一维数组来表示int[] queuePos = new int[n]. 每一个格子表示这行上皇后的位置。

  • 首先一个行只有一个皇后的位置,所以行自然没有重复的皇后

  • 对于列,我们寻找到现在这一行之前的所有行,有没有皇后已经被放在同样的列上,如果没有就可以放

  • 对于斜角,处在斜角上的格子有一个性质Math.abs(row - rowWeWannaPlace) == Math.abs(queuePos[row] - colWeWannaPlace). 所以也是检查一遍就行了

helper函数接受两个参数,一个queuePos的一维数组,一个当前行

伪代码:

如果当前行 == n

  添加结果

不然对于每一列

  如果这个位置能放

    放皇后在这个位置上

    递归helper(row + 1)

所以整体的代码是:

public List<List<String>> solveNQueens(int n) {
    List<List<String>> res = new ArrayList<>();
    int[] queuePos = new int[n];
    Arrays.fill(queuePos, -1);
    queue(res, queuePos, 0);
    return res;
}

private boolean canPlace(int[] queuePos, int row, int col) {
    for(int i = 0; i < row; i++) {
        if(queuePos[i] == col) {
            return false;
        }
        if(Math.abs(i - row) == Math.abs(queuePos[i] - col)) {
            return false;
        }
    }
    return true;
}

private void queue(List<List<String>> res, int[] queuePos, int row) {
    int n = queuePos.length;
    if(row == n) {
        List<String> cur = generateResStr(queuePos);
        res.add(cur);
        return;
    }
    for(int i = 0; i < n; i++) {
        if(canPlace(queuePos, row, i)) {
            queuePos[row] = i;
            queue(res, queuePos, row + 1);
        }
    }
}

private List<String> generateResStr(int[] queuePos) {
    int n = queuePos.length;
    char[] row = new char[n];
    Arrays.fill(row, '.');
    List<String> res = new ArrayList<>();
    for(int i = 0; i < queuePos.length; i++) {
        row[queuePos[i]] = 'Q';
        res.add(new String(row));
        Arrays.fill(row, '.');
    }
    return res;
}

相当于遍历一棵树,树的层数是N,每层的节点数数是可以放的列,所以总复杂度是O(n!)

results matching ""

    No results matching ""