leetcode 51——N皇后
解题思路:
这个题目是最经典的回溯问题(dfs搜索)。只是在八皇后问题的基础上变为了n皇后问题,并且以字符串的形式输出。这一类题目的解题过程主要都是套模板。模板的思路大概如下:
- 首先,使用递归结构。和深度优先搜索很相似,如以下伪代码:
void dfs(now_node){
//遍历与当前结点相邻的所有结点
for(node=first_node;node!=end_node;node=next_node){
if(node没有被访问过){
visit(node);
dfs(node);
}
}
}
- 但是我们的目的不是遍历所有的结点,而是想在搜索树中找到叶节点(也就是顺利的找到第n个皇后可以的位置)作为可行解。而且还多出了一些约束条件。最终代码如下:
class Solution {
public:
/*递归函数dfs
n表示这是一个n皇后问题
index表示目前正在处理第index行
model用于存储输出的模板
answer用于存储所有的结果
result用于存储一次尝试的过程
后三个参数是标记当前位置是否被访问过*/
void n_queen(int n,int index,vector<string>&model,vector<vector<string>>&answer,vector<int>&result,vector<bool> &line_visited,vector<bool> &left_visited,vector<bool> &right_visited){
if(index==n){
vector<string> tmp;
for(int i=0;i<n;++i){
tmp.push_back(model[result[i]]);
}
answer.push_back(tmp); //找到可行解,加入解集
}
else{
for(int i=0;i<n;++i){
if(!line_visited[i]&&!left_visited[i-index+n-1]&&!right_visited[i+index]){
result.push_back(i);
line_visited[i]=true;
left_visited[i-index+n-1]=true;
right_visited[i+index]=true;
n_queen(n,index+1,model,answer,result,line_visited,left_visited,right_visited);
result.pop_back();
line_visited[i]=false;
left_visited[i-index+n-1]=false;
right_visited[i+index]=false;
}
}
}
}
vector<vector<string>> solveNQueens(int n) {
vector<bool> line_visited(n,false); //当前列是否被访问
vector<bool> left_visited(n,false); //当前\方向的斜线是否被访问
vector<bool> right_visited(n,false); //当前/方向的斜线是否被访问
string tmp;
tmp.insert(0,n,'.');
vector<string> model(n,tmp);
for(int i=0;i<n;++i){
model[i][i]='Q';
}
vector<vector<string>>answer;
vector<int>result;
n_queen(n,0,model,answer,result,line_visited,left_visited,right_visited);
return answer;
}
};
搞清楚这个模板的思路,累死的题目,比如全排列等就套用就可以了。