Then-queens puzzle is the problem of placingn_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.."]
]
Solution
The same as N-Queens, just need to output size of results.
class Solution {
public int totalNQueens(int n) {
List<List<Integer>> ans = new ArrayList<>();
if (n <= 0) {
return 0;
}
searchHelper(n, new ArrayList<Integer>(), ans);
return ans.size();
}
// Backtracking recursively find the valid solutions
private void searchHelper(int n, List<Integer> cols, List<List<Integer>> ans) {
if (cols.size() == n) {
ans.add(new ArrayList<Integer>(cols));
return;
}
for (int col = 0; col < n; col++) {
if (!isValid(col, cols)) {
continue;
}
cols.add(col);
searchHelper(n, cols, ans);
cols.remove(cols.size() - 1);
}
}
// Check if the new position to be placed is invalid
private boolean isValid(int col, List<Integer> cols) {
if (cols.size() == 0) {
return true;
}
for (int row = 0; row < cols.size(); row++) {
if (col == cols.get(row)) {
return false;
}
if (cols.get(row) - row == col - cols.size()) {
return false;
}
if (cols.get(row) + row == col + cols.size()) {
return false;
}
}
return true;
}
}
Or just use a global variable
class Solution {
private static int total;
public int totalNQueens(int n) {
List<List<Integer>> ans = new ArrayList<>();
if (n <= 0) {
return 0;
}
total = 0;
searchHelper(n, new ArrayList<Integer>());
return total;
}
// Backtracking recursively find the valid solutions
private void searchHelper(int n, List<Integer> cols) {
if (cols.size() == n) {
total++;
return;
}
for (int col = 0; col < n; col++) {
if (!isValid(col, cols)) {
continue;
}
cols.add(col);
searchHelper(n, cols);
cols.remove(cols.size() - 1);
}
}
// Check if the new position to be placed is invalid
private boolean isValid(int col, List<Integer> cols) {
if (cols.size() == 0) {
return true;
}
for (int row = 0; row < cols.size(); row++) {
if (col == cols.get(row)) {
return false;
}
if (cols.get(row) - row == col - cols.size()) {
return false;
}
if (cols.get(row) + row == col + cols.size()) {
return false;
}
}
return true;
}
}
有关全局变量:
@mnmunknown
既然不需要输出最终解,也就省去了传递 rst 和把棋盘转成 String 的过程。一个问题是,如何在这种dfs + backtracking中维护一个 primitive type 变量,比如有效解的总数?
Java 中默认 primitive type 是 pass by value,而且 Integer type 虽然作为一个 object 存在但是是 immutable, 不能用来作为全局参数多个函数共同更新。
直接建全局变量太蠢了,也不好看。
Not using global variable
public class Solution {
public int totalNQueens(int n) {
return dfs(0, n, new boolean[n], new boolean[2*n - 1], new boolean[2*n - 1]);
}
private int dfs(int row, int n, boolean[] cols, boolean[] diag45, boolean[] diag135){
if(row == n){
return 1;
}
int solutionCount = 0;
for(int col = 0; col < n; col++){
if(!cols[col] && !diag45[row + col] && !diag135[row - col + n - 1]){
cols[col] = true;
diag45[row + col] = true;
diag135[row - col + n - 1] = true;
solutionCount += dfs(row + 1, n, cols, diag45, diag135);
cols[col] = false;
diag45[row + col] = false;
diag135[row - col + n - 1] = false;
}
}
return solutionCount;
}
}