【刷题笔记】N皇后||回溯||符合思维方式
2023-12-14 12:03:20
N皇后II
1 题目详情
n 皇后问题 研究的是如何将 n 个皇后放置在 n × n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。
https://leetcode.cn/problems/n-queens-ii/
2 分析
刚一开始的时候我认为这道题很难,防止n个皇后在同一行这件事很容易,我们在递归的时候,每次调用递归函数,将当前放置的皇后的所在行标记为true,这样下一列我们在放皇后的时候,前面皇后的所在行都不能防止皇后。
但是难就难在,如何确定让皇后们不在同一条斜线上?
斜率为1的斜线,斜线上所有的皇后所在点的y-x
都是等值的。斜率为-1的斜线,斜线上所有的皇后所在点的x+y
都是等值的,我们只需要记录下当前步骤放置的皇后所在点的x+y
和x-y
的值,那么就相当于记录下了该皇后所在的两条斜线。
3 代码
class Solution {
int res = 0;
Set<Integer> sets1 = new HashSet<>(); // 记录斜率为1的斜线
Set<Integer> sets2 = new HashSet<>(); // 记录斜率为-1的斜线
public int totalNQueens(int n) {
dfs(new boolean[n], n, 0);
return res;
}
public void dfs(boolean[] visted_row, int n, int index) {
if (index == n) { // index其实表示的是当前所在列
res++;
return;
}
for (int i = 0; i < n; i++) {
if (visted_row[i]) continue;
int real_row = i + 1; // y
int real_col = index + 1; // x
if (sets1.contains(real_row-real_col)) continue;
if (sets2.contains(real_row+real_col)) continue;
sets1.add(real_row-real_col); // 记录y-x
sets2.add(real_row+real_col); // 记录y+x
visted_row[i] = true;
dfs(visted_row, n, index + 1);
visted_row[i] = false;
sets1.remove(real_row-real_col); // 移除
sets2.remove(real_row+real_col); // 移除
}
}
}
那么我们用同样的方法也可以做51. N 皇后,只需要在每次dfs的时候记录下当前皇后的坐标,最后创建n*n的棋盘,所有点置为.
,然后将皇后坐标置为Q
。
class Solution {
List<List<String>> res = new ArrayList<>();
Set<Integer> sets1 = new HashSet<>(); // 记录斜率为1的斜线
Set<Integer> sets2 = new HashSet<>(); // 记录斜率为-1的斜线
List<int[]> points = new ArrayList<>();
List<List<int[]>> total_points = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
List<List<String>> res = new ArrayList<>();
dfs(new boolean[n], n, 0);
// 将total_points中的每个point_list变换成n*n的矩阵,有点的地方变成Q,没有点的地方变成.
for (List<int[]> point_list : total_points) {
char[][] matrix = new char[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(matrix[i], '.');
}
for (int[] point : point_list) {
matrix[point[0]][point[1]] = 'Q';
}
List<String> matrix_str = new ArrayList<>();
for (int i = 0; i < n; i++) {
matrix_str.add(new String(matrix[i]));
}
res.add(matrix_str);
}
return res;
}
public void dfs(boolean[] visted_row, int n, int index) {
if (index == n) { // index其实表示的是当前所在列
total_points.add(new ArrayList<>(points));
return;
}
for (int i = 0; i < n; i++) {
if (visted_row[i]) continue;
int real_row = i + 1; // y
int real_col = index + 1; // x
if (sets1.contains(real_row-real_col)) continue;
if (sets2.contains(real_row+real_col)) continue;
sets1.add(real_row-real_col); // 记录y-x
sets2.add(real_row+real_col); // 记录y+x
visted_row[i] = true;
points.add(new int[]{index, i});
dfs(visted_row, n, index + 1);
points.remove(points.size() - 1);
visted_row[i] = false;
sets1.remove(real_row-real_col); // 移除
sets2.remove(real_row+real_col); // 移除
}
}
}
文章来源:https://blog.csdn.net/qq_42898299/article/details/134990277
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!