题解 | #N皇后问题#

N皇后问题

http://www.nowcoder.com/practice/c76408782512486d91eea181107293b6

题解:回溯
首先,每个皇后不能同行,不能同列,不能同斜线。
对于一个3皇后问题,如图:
图片说明

约束条件判断: 同行和同列好判断,同斜线判断如图:
图片说明

可以看出斜线约束判断([ (i-1)-(j-1),(i-j),(i+1)-(j+1) ], [ (i+1)+(j-1),(i+j),(i-1)+(j+1) ]
递归函数分析:
 递归边界: cur==n 表明 每个皇后都已放好
 递归过程:尝试这在第cur行的某个位置放皇后 graph[cur] =i, 并判断是否与之前放置的皇后有冲突。 如果没有,就去在第cur+1行放置皇后。
 回溯: 如果有冲突了,将graph[cur] 恢复状态。

复杂度分析:
时间复杂度:: 首先每一行有N的位置可以放.
空间复杂度: : 申请一个数组保存放置状态,且递归栈长度也为N
实现如下:

class Solution {
public:
    /**
     *
     * @param n int整型 the n
     * @return int整型
     */
    void dfs(int n,vector<int>& graph,int cur,int &ans){
        if(cur == n) { ans++; return;}
        for(int i = 0;i<n;i++){
            graph[cur] = i;  //尝试这在i处放
            int ok = 0;
            //与之前放置的冲突否
            for(int j = cur-1;j>=0;j--){
                if(i == graph[j]||graph[j]+j==cur+i||j-graph[j]==cur-i) {ok = 1; break;}
            }
            //当前没有冲突,就开始新的一行
            if(!ok) dfs(n,graph,cur+1,ans);
            //有冲突,回溯,恢复状态
            graph[cur] = -1;
        }
    }
    int Nqueen(int n) {
        // write code here
        int ans = 0;vector<int> graph(n,-1);
        dfs(n, graph, 0, ans);
        return ans;
    }
};

题解二:优化上面的回溯
在上面的每次判断冲突都需要遍历之前的放置的位置,但是观察可以发现每一列可以用一个标志表示这一列以及放置了皇后,同时,斜线上可以用一个标志代表这个斜线上已经有皇后了。
图示:
图片说明

用一个二维数组vis来保存每个标志

复杂符分析:
时间复杂度:,同题解一
空间复杂度:,同题解一

实现如下:

class Solution {
public:
    /**
     *
     * @param n int整型 the n
     * @return int整型
     */
    int ans = 0;
    int vis[3][30]={0};
    void dfs(int cur,int n){
        if(cur==n) {++ans;return;}
        for(int i = 0;i<n;i++){
            //判断3个标志
            if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n]){
                vis[0][i] = vis[1][cur+i]=vis[2][cur-i+n] = 1;
                dfs(cur+1,n);
                vis[0][i] = vis[1][cur+i]=vis[2][cur-i+n] = 0; // 回溯
            }
        }
    }
    int Nqueen(int n) {
      dfs(0,n);
      return ans;
    }
};
牛客网编程题题解 文章被收录于专栏

本专栏记录在牛客网上AC的每一题,写下题解。 未来2年完成2000编程题的题解。 2021.12.29更新,最进准备毕设,断更了,会尽快做完毕设,继续做这一件事情

全部评论
分析 graph[j]+j==cur+i||j-graph[j]==cur-i, 等价于: ① graph[j] - i = cur - j ② graph[j] - i = j - cur 等价于: abs(graph[j] - i) = abs(cur - j)
点赞
送花
回复
分享
发布于 2022-10-05 18:14 美国

相关推荐

6 1 评论
分享
牛客网
牛客企业服务