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:4Output:[ [".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不超过32或64,但是最快的答案就是用位运算做出来的。如果n比较大,位运算就没法做了。
要注意的是,用位运算的时候,左移、右移的变量要分开,不能混在一起。因为一个棋子影响范围不能拐弯,只能走横、竖、斜45°其中之一走到底。
// bitmask版本,假设n <= 32
class Solution {
private int lrExists = 0;
private int rlExists = 0;
private int vertExists = 0;
private char[] row = null;
private int ONE = 1 << 31;
public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new LinkedList<>();
if (n > 32) {
System.out.println("n >= 32 !, n: " + n);
return res;
}
ArrayList<String> board = new ArrayList<>(n);
row = new char[n];
Arrays.fill(row, '.');
backtrace(board, n, res, 0, 0);
return res;
}
private void backtrace(ArrayList<String> board, int n, List<List<String>> res, int i, int count) {
if (i == n || count == n) {
res.add(new ArrayList<>(board));
return;
}
for (int j = 0; j < n; j++) {
int jMask = ONE >>> j;
if (((lrExists & jMask) == 0) && ((rlExists & jMask) == 0) && ((vertExists & jMask) == 0)) {
int oldVertExists = vertExists;
int oldLrExists = lrExists;
int oldRlExists = rlExists;
vertExists |= jMask;
lrExists = (lrExists | jMask) >>> 1;
rlExists = (rlExists | jMask) << 1;
row[j] = 'Q';
board.add(String.valueOf(row));
row[j] = '.';
// System.out.println(String.format("i: %d, j: %d, count: %d", i, j, count));
// System.out.println("board: " + Arrays.deepToString(board.toArray()));
// System.out.println(Integer.toBinaryString(vertExists));
// System.out.println(Integer.toBinaryString(lrExists));
// System.out.println(Integer.toBinaryString(rlExists));
backtrace(board, n, res, i + 1, count + 1);
vertExists = oldVertExists;
lrExists = oldLrExists;
rlExists = oldRlExists;
board.remove(board.size() - 1);
}
}
}
}
// 非位运算版本:
/*class Solution {
private boolean[] lrExists = null; // top-left to right-bottom
private boolean[] rlExists = null;
private boolean[] vertExists = null;
private char[] row = null;
public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new LinkedList<>();
ArrayList<String> board = new ArrayList<>(n);
lrExists = new boolean[2 * n - 1];
rlExists = new boolean[2 * n - 1];
vertExists = new boolean[n];
row = new char[n];
Arrays.fill(row, '.');
backtrace(board, n, res, 0, 0);
return res;
}
private void backtrace(ArrayList<String> board, int n, List<List<String>> res, int i, int count) {
if (i == n || count == n) {
res.add(new ArrayList<>(board));
return;
}
// System.out.println(String.format("i: %d, j: %d, count: %d", i, j, count));
// System.out.println("board: " + Arrays.deepToString(board.toArray()));
for (int j = 0; j < n; j++) {
if (!(vertExists[j] || rlExists[j - i + (n - 1)] || lrExists[i + j])) {
vertExists[j] = rlExists[j - i + (n - 1)] = lrExists[i + j] = true;
row[j] = 'Q';
board.add(String.valueOf(row));
row[j] = '.';
backtrace(board, n, res, i + 1, count + 1);
vertExists[j] = rlExists[j - i + (n - 1)] = lrExists[i + j] = false;
board.remove(board.size() - 1);
}
}
}
}*/