题目:N皇后 II middle
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
示例:
输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
思路:
就是51题的简化版
package leetCode.DFS;
import java.util.ArrayList;
import java.util.List;
public class lc_dfs_52_totalNQueens {
public int totalNQueens(int n) {
List<List<Integer>> ans = new ArrayList<>();
if (n <= 0)
return 0;
boolean[] IscolumnPlaced = new boolean[n];
boolean[] rightTilt = new boolean[2 * n];//为什么是2n-1个,为啥写2n
boolean[] leftTilt = new boolean[2 * n];
dfs(0, n, new ArrayList<Integer>(), ans, IscolumnPlaced, rightTilt, leftTilt);
return ans.size();
}
/**
* @param row 第几行,从0开始
* @param n n个皇后
* @param place 放置皇后列的位置,共n个数,第i个数num代表i行的第num列,i从0开始
* @param ans 最后的结果
* @param IscolumnPlaced 该列是否被放置
* @param rightTilt 右斜对角,共2*n-1个右斜对角,记录是否被放置,每个右斜对角row-col是常数
* @param leftTilt 左斜对角,共2*n-1个左斜对角,每个左斜对角row+col是常数
*/
public void dfs(int row, int n, List<Integer> place, List<List<Integer>> ans,
boolean[] IscolumnPlaced, boolean[] rightTilt, boolean[] leftTilt) {
if (row >= n) {
ans.add(new ArrayList<Integer>(place));
}
for (int col = 0; col < n; col++) {
// 行不用判断重复,因为每次都递增一行,row+1,所以不会重复
if (!IscolumnPlaced[col] && !rightTilt[row - col + n] && !leftTilt[row + col]) {
place.add(col);//放置的是皇后在row行的col列
IscolumnPlaced[col] = true;
// 右斜对角的范围从-(n-1)~(n-1),将其+n,防止溢出全部变为正数,变成1~(2n-1),所以rightTilt[2*n]
rightTilt[row - col + n] = true;
// 左斜对角没有负数不会溢出,直接相加,最大为2(n-1),为了统一大小也写为2n
leftTilt[row + col] = true;
dfs(row + 1, n, place, ans, IscolumnPlaced, rightTilt, leftTilt);
//该位置试完后记得弹出并将访问过的位置置为没访问
place.remove(place.size() - 1);
IscolumnPlaced[col] = false;
rightTilt[row - col + n] = false;
leftTilt[row + col] = false;
}
}
}
}