LeetCode 51.N皇后(下标映射)

LeetCode 51.N皇后

题意

在n*n的棋盘上,放上n个皇后,两个皇后不可以放在同一行、同一列、同一正对角线和同一副对角线。
给一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

分析

每进入一行,遍历这一行的所有位置,每遍历到新的位置,检查这个位置所在的列、主对角线和副对角线是否三者都
没有放皇后,如果满足,则在当前位置尝试放皇后,进入下一行;如果不满足,继续往右遍历。
1.每次都是一行一行的放皇后,因此可以认为在当前行放皇后时,上面的每一行都已经了放了一个皇后,
所以不需要数组来记录状态。

2.使用数组col来记录每一列是否放置了皇后。

3.分别使用数组dg和udg来记录每条对角线和每条副对角线上是否放置了皇后。
设列的索引为y,行的索引为x,则正对角线可以表示为y=x+k,k为直线的截距,不同的直线有不同的截距k,
而副对角线可以表示为y=-x+b,同样,b为直线的截距。

则每条正对角线可以使用截距k来区分,即 k=y-x ;
条副对角线也可以使用截距来区分,即 b=y+x 。
需要注意的是,k=y-x有可能是负数,而数组的索引是不能为负的。
Attention:此题是需要回溯的,因此要恢复现场。

代码

class Solution {
public:
    int n;
    vector<vector<string>> ans;//用于存储放置了n个皇后的棋盘状态
    vector<string> t;//用于存储当前棋盘的状态
    //col用于记录每一列放置皇后的状态,dg用于记录每一条正对角线放置皇后的状态,udg用于记录每一条副对角线放置皇后的状态
    vector<int> col, dg, udg;

    vector<vector<string>> solveNQueens(int n1) {
        n = n1;
        t = vector<string>(n, string(n, '.'));//初始化棋盘
        col = vector<int> (n);
        dg = udg = vector<int> (2 * n);

        dfs(0);//从索引为0的行开始遍历
        return ans;
    }

    //暴力搜索
    void dfs(int u) {
        //如果u等于n,则说明索引0到u-1的行都遍历过了,可以直接返回答案
        if (u == n) {
            ans.push_back(t);
            return;
        }

        for (int i = 0; i < n; i++) {
            //只有当前位置所在的行、列、正对角线以及副对角线都没有皇后,才可以尝试放置皇后
            if (!col[i] && !dg[i - u + n] && !udg[i + u]) {
                col[i] = dg[i - u + n] = udg[i + u] = 1;
                t[u][i] = 'Q';//在当前位置放皇后
                //在当前位置放了皇后,即这一行就有皇后了,去下一行尝试放皇后
                dfs(u + 1);
                
                //恢复现场
                col[i] = dg[i - u + n] = udg[i + u] = 0;
                t[u][i] = '.';
            }
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值