代码,由全排列转化而来,加上剪枝,整洁的代码:
共有4个变量,res(最终的结果),level,当前合理的解,n皇后的个数,visit,当前列是否放过皇后,由于本来就是在新的行方皇后,又通过visit判定,因此当前的新皇后肯定不在以往的行和列。因此只需要对新加的皇后判断斜对角是否符合要求;
class Solution { public: vector<vector<string>> solveNQueens(int n) { if(n==0) return {}; vector<vector<string>> res; vector<int> visit(n,0); vector<int> level; dfs(res,level,visit,n); return res; } void dfs(vector<vector<string>>&res,vector<int>&level,vector<int>&visit,int n){ if(level.size()==n){ vector<string> vs(n,string(n,'.')); for(int i=0;i<n;i++){ int j=level[i]; vs[i][j]='Q'; } res.push_back(vs); return; } for(int j=0;j<n;j++){ if(visit[j]==0 && isvalid(level,j)){ visit[j]=1; level.push_back(j); dfs(res,level,visit,n); visit[j]=0; level.pop_back(); } } } bool isvalid(vector<int>&level,int y){ int x=level.size(); for(int i=0;i<x;i++){ int j=level[i]; if(abs(y-j)==x-i) return false; } return true; } };
其实就是全排列问题+剪枝,也是很经典很经典
代码:
class Solution { public: vector<vector<string>> solveNQueens(int n) { vector<vector<string>> res; vector<int> pos(n,-1);//记录第i+1行的皇后,应该放在第j+1列 int row=0; DFS(n,row,pos,res); return res; } void DFS(int n,int row,vector<int>& pos,vector<vector<string>>& res){ //回溯法,能到下一条语句一定合法 //递归边界1,得到最终的解; if(row==n){ vector<string> temp(n,string(n,'.')); for(int i=0;i<n;i++){ temp[i][pos[i]]='Q'; } res.push_back(temp); }else{ for(int col=0;col<n;col++){ //新加皇后到row+1行,col+1列合法,进入子问题;如果新皇后怎么加都无效,则本次循环结束,col+1进行下一次循环 //判断是否需要向子问题递归,不需要则返回上一层; if(isvalid(pos,row,col)){ pos[row]=col; DFS(n,row+1,pos,res); pos[row]=-1; } } } } bool isvalid(vector<int>& pos,int row,int col){ //判断是否放在了已经有皇后的列上,以及是否在同一对角线上; for(int i=0;i<row;i++){ if((col==pos[i])||(abs(row-i)==abs(col-pos[i]))) return false; } return true; } };