leetcode 0051
说明
只是为了记录一下,不求多快,也不深究。
会简要描述思路,代码中不写注释。
如碰到不会做的用了别人代码会在博客中标出。
题目描述
参考
参考了leetcode官方题解,链接如下:
思路
官方叫回溯,说白了还是深搜,主要是斜线线的判断条件麻烦一点,用两个数组分别给各条斜线编号。
mains代表主斜线,主斜线上的点满足row-col为常数,共有2n-1条;
将右上角的线编号为0的话,编号就是row-col+n-1。
secondary代表副斜线,副斜线上的点满足row+col为常数,也是2n-1条;
将左上角的线编号为0的话,编号就是row+col。
放置皇后时要判读该位置是否能被攻击,放置完毕后,更新cols,mains和secondary。
从第0行开始逐一放置,若来到了第n行,证明前n已放置完毕,将可行方案加入列表。
class Solution {
List<List<String>> ll = new ArrayList<List<String>>();
int[] cols;
int[] mains;
int[] secondary;
int[] queens;
int n;
public List<List<String>> solveNQueens(int n) {
cols = new int[n];
mains = new int[2 * n - 1];
secondary = new int[2 * n - 1];
queens = new int[n];
this.n = n;
backTrack(0);
return ll;
}
public void backTrack(int row) {
if (row == n) {
addToList();
return;
}
for (int col = 0; col < n; col++) {
if (isOkToPut(row, col)) {
putQueen(row, col);
} else {
continue;
}
backTrack(row + 1);
removeQueen(row, col);
}
}
private void addToList() {
List<String> ls = new ArrayList<String>();
for (int queen : queens) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
if (i == queen) {
sb.append('Q');
} else {
sb.append('.');
}
}
ls.add(sb.toString());
}
ll.add(ls);
}
public boolean isOkToPut(int row, int col) {
if (cols[col] == 0 && mains[row - col + n - 1] == 0 && secondary[row + col] == 0) {
return true;
} else {
return false;
}
}
public void putQueen(int row, int col) {
queens[row] = col;
cols[col] = 1;
mains[row - col + n - 1] = 1;
secondary[row + col] = 1;
}
public void removeQueen(int row, int col) {
queens[row] = 0;
cols[col] = 0;
mains[row - col + n - 1] = 0;
secondary[row + col] = 0;
}
}