昨晚开始就和宇妹一起重新刷Leetcode
==================================================
#1 问题:
N-Queens问题其实就是把N个皇后放在N * N的国际象棋板上面,保证每个皇后不会“吃掉”对方(皇后的攻击范围是横、竖和两条对角线)。第一个问题是输出所有可能的Queen的放置状态,第二个问题是求解有多少种放置方法。
原题:
==================================================
#2 算法:
DFS。假设已经把 ( i-1 )行的皇后都放置好了,看第 i 行。对该行上面每一列 ( j = 0; j < n; j++) 都进行检查,如果可行就放置在 (i , j),然后扩展状态。
检查是否可行其实就是检查横、竖和两条对角线。
DFS的终止条件是 i == n,表明已经检查到最后一行了,对搜索到得结果进行处理。
==================================================
#3 数据结构:
int[] pos = int[n],其中pos[i] = j 表示第 i 行上面的Queen是放置在第 j 列上面。
==================================================
#4 代码:
N-Queens-1
public class Solution {
public List<String[]> solveNQueens(int n) {
int[] pos = new int[n]; // pos[i] = j means put a queue in position(i,j)
List<String[]> res = new ArrayList<String[]>();
solve(0, n, pos, res);
return res;
}
// dfs
public void solve(int row, int n, int[] pos, List<String[]> res) {
if (row == n) {
// find one solution
String[] s = new String[n];
for (int i = 0; i < n; i++) {
String str = "";
for (int j = 0; j < n; j++) {
if (pos[i] == j) str += "Q";
else str += ".";
}
s[i] = str;
}
res.add(s);
return ;
}
for (int j = 0; j < n; j++) {
if (isValid(row, j, pos)) {
pos[row] = j;
solve(row+1, n, pos, res);
}
}
return ;
}
// check if can put elements into position (i,j)
public boolean isValid(int i, int j, int[] pos) {
for (int k = 0; k < i; k++) {
if (pos[k] == j) return false; // check column
if (pos[k] + k == j + i) return false; // check diagonal
if (pos[k] - k == j - i) return false; // check counter-diagonal
}
return true;
}
}
N-Queens-2
public class Solution {
public int totalNQueens(int n) {
int[] pos = new int[n]; // pos[i] = j means put a queue in position(i,j)
return solve(0, n, pos);
}
// dfs
public int solve(int row, int n, int[] pos) {
int count = 0;
if (row == n) return 1; // find a solution
for (int j = 0; j < n; j++) {
if (isValid(row, j, pos)) {
pos[row] = j;
count += solve(row+1, n, pos);
}
}
return count;
}
// check if can put elements into position (i,j)
public boolean isValid(int i, int j, int[] pos) {
for (int k = 0; k < i; k++) {
if (pos[k] == j) return false; // check column
if (pos[k] + k == j + i) return false; // check diagonal
if (pos[k] - k == j - i) return false; // check counter-diagonal
}
return true;
}
}