52. N皇后 II
给同学讲一下思考dfs的方法论
1. 思考dfs每个状态的含义
dfs(row)代表当前在第row+1行放置皇后
class Solution {
public:
vector<int> board;
int limit;
int ans;
void dfs(int row){
}
int totalNQueens(int n) {
//board[i] = j: 第i+1行的皇后被放在j+1列
board.resize(n);
//当row == limit,代表找到一种解,应当返回
limit = n;
//记录解法的种类
ans = 0;
dfs(0);
return ans;
}
};
2. 写出dfs的状态转移
class Solution {
public:
vector<int> board;
int limit;
int ans;
void dfs(int row){
//<1>
for(int i=0;i<limit;++i){
//放下该行的皇后
board[row] = i;
//处理下一行
dfs(row+1)
}
//<1>
}
int totalNQueens(int n) {
board.resize(n);
limit = n;
ans = 0;
dfs(0);
return ans;
}
};
3. 结束条件
class Solution {
public:
vector<int> board;
int limit;
int ans;
void dfs(int row){
//<2>
//找到并返回
if(row == limit){
ans++;
return ;
}
//<2>
//<1>
for(int i=0;i<limit;++i){
//放下该行的皇后
board[row] = i;
//处理下一行
dfs(row+1)
}
//<1>
}
int totalNQueens(int n) {
board.resize(n);
limit = n;
ans = 0;
dfs(0);
return ans;
}
};
4. 判定限制条件
本题限制条件:皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。
class Solution {
public:
vector<int> board;
int limit;
int ans;
void dfs(int row){
//<2>
if(row == limit){
ans++;
return ;
}
//<2>
//<1>
for(int i=0;i<limit;++i){
//放下该行的皇后
board[row] = i;
//<3>
bool ok = true;
for(int k=0;k<row;++k){
//同一列或者斜线上
if(board[k] == i || abs(k - row) == abs(board[k] - i)){
ok = false;
break;
}
}
//<3>
//进入下一个状态
if(ok){
//处理下一行
dfs(row+1);
}
}
//<1>
}
int totalNQueens(int n) {
board.resize(n);
limit = n;
ans = 0;
dfs(0);
return ans;
}
};
5. 无注释完整代码
class Solution {
public:
vector<int> board;
int limit;
int ans;
void dfs(int row){
if(row == limit){
ans++;
return ;
}
for(int i=0;i<limit;++i){
board[row] = i;
bool ok = true;
for(int k=0;k<row;++k){
if(board[k] == i || abs(k - row) == abs(board[k] - i)){
ok = false;
break;
}
}
if(ok){
dfs(row+1);
}
}
}
int totalNQueens(int n) {
board.resize(n);
limit = n;
ans = 0;
dfs(0);
return ans;
}
};