leetcode 51 N皇后问题

 

 

 代码,由全排列转化而来,加上剪枝,整洁的代码:

共有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;
    }
};

 

posted @ 2019-04-12 22:23  Joel_Wang  阅读(139)  评论(0编辑  收藏  举报