深度优先搜索和N皇后 —— Leetcode 面试题 08.12. 八皇后

题目如下:

题目 N皇后

设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的“对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。

首先定义棋盘二维数组chessmap,对于里面的每一个整数,0代表可放置皇后,1代表已经放置皇后,2代表已知的皇后覆盖的不可放置区域。

实现每次放置皇后后棋盘状态的修改:

void changeStatus(vector<vector<int>>& nextmap,int x,int y){
    int length = nextmap.size();
    for(int i=0;i<length;i++){
        nextmap[x][i] = 2;
        nextmap[i][y] = 2;
        changeDiag(nextmap,x,y,{-1,1});
        changeDiag(nextmap,x,y,{1,1});
        changeDiag(nextmap,x,y,{1,-1});
        changeDiag(nextmap,x,y,{-1,-1});
    }
    nextmap[x][y] = 1;
    int offset = 0;
}

循环体里面前两行为修改行和列,修改对角线略微复杂故封装了一个新函数去修改对角线,代码如下:

void changeDiag(vector<vector<int>>& nextmap,int iptx,int ipty,vector<int> offset){
    int length = nextmap.size();
    int dx = offset[0];
    int dy = offset[1];
    int x = iptx; int y = ipty;
    while(( 0<=x&&x<length ) && (0<=y&&y<length)){
        nextmap[x][y] = 2;
        x += dx;
        y += dy;
    }
}

输入的offset(偏移量)代表了修改对角线的方向(射线的方向)。

利用上述函数去搞dfs,注意迭代次数超过棋盘边长时要输出答案并且停止迭代,完整代码如下:

void dfs(vector<vector<int>> chessmap,int n,vector<vector<string>>& ans){
    vector<vector<int>> nextmap = chessmap;
    int length = chessmap.size();
    if(n==length){
        vector<string> ret(length);
        for(int i=0;i<length;i++){
            for(int j=0;j<length;j++){
                if(chessmap[i][j]==1){
                    ret[i].push_back('Q');
                }
                else ret[i].push_back('.');
            }
        }
        ans.push_back(ret);
        return;
    }
    for(int i=0;i<length;i++){
        if(nextmap[n][i]==0){
            changeStatus(nextmap,n,i);
            dfs(nextmap,n+1,ans);
            nextmap = chessmap;
        }
    }
}

最后注意函数的顺序:修改对角线的函数需要定义在修改状态函数的前面,否则会报错(或者可以先声明函数),完整代码实现如下:

class Solution {
public:

void changeDiag(vector<vector<int>>& nextmap,int iptx,int ipty,vector<int> offset){
    int length = nextmap.size();
    int dx = offset[0];
    int dy = offset[1];
    int x = iptx; int y = ipty;
    while(( 0<=x&&x<length ) && (0<=y&&y<length)){
        nextmap[x][y] = 2;
        x += dx;
        y += dy;
    }
}

void changeStatus(vector<vector<int>>& nextmap,int x,int y){
    int length = nextmap.size();
    for(int i=0;i<length;i++){
        nextmap[x][i] = 2;
        nextmap[i][y] = 2;
        changeDiag(nextmap,x,y,{-1,1});
        changeDiag(nextmap,x,y,{1,1});
        changeDiag(nextmap,x,y,{1,-1});
        changeDiag(nextmap,x,y,{-1,-1});
    }
    nextmap[x][y] = 1;
    int offset = 0;
}

void dfs(vector<vector<int>> chessmap,int n,vector<vector<string>>& ans){
    vector<vector<int>> nextmap = chessmap;
    int length = chessmap.size();
    if(n==length){
        vector<string> ret(length);
        for(int i=0;i<length;i++){
            for(int j=0;j<length;j++){
                if(chessmap[i][j]==1){
                    ret[i].push_back('Q');
                }
                else ret[i].push_back('.');
            }
        }
        ans.push_back(ret);
        return;
    }
    for(int i=0;i<length;i++){
        if(nextmap[n][i]==0){
            changeStatus(nextmap,n,i);
            dfs(nextmap,n+1,ans);
            nextmap = chessmap;
        }
    }
}
    vector<vector<string>> solveNQueens(int n) {
    int length = n;
    vector<vector<string>> ans;
    vector<vector<int>> chessmap(length,vector<int>(length,0));
    dfs(chessmap,0,ans);
    return ans;
    }
};

提交,过了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值