每天一道LeetCode-----n皇后问题 - Go语言中文社区

每天一道LeetCode-----n皇后问题


N-Queens

原题链接N-Queens
这里写图片描述
n皇后问题,和数独问题一样,都是回溯法的经典题目。
n皇后问题约束是任意两个皇后不能在一行,不能在一列,不能在同一个45度直线,不能在同一个135度直线上。所以求解时需要记录

  • 当前行是否已经存在一个皇后
  • 当前列是否已经存在一个皇后
  • 当前位置所在的45度直线上是否已经存在一个皇后
  • 当前位置所在的135度直线上是否已经存在一个皇后

因为n行n个皇后,所以每一行有且仅有一个皇后,那么可以不需要记录当前行是否已经存在皇后,只要在当前行找到一个位置容纳皇后,就开始在下一行寻找,即每一行遍历右边列,找到满足后三个条件的位置即可。

所有的约束条件都可以用数组记录,即

  • flag_col[column]表示column列是否已经存在一个皇后
  • flag_45[p]表示位置[row, column]所在的45度直线是否出现过皇后,其中p是row和column的函数
  • flag_135[q]表示位置[row, column]所在的135度直线是否出现过皇后,其中q是row和column的函数

比较不要记录的就是45度和135度直线上的情况,可以利用数学思维简化。

  • 对于45度直线,可知斜率为1,即解析式可以写成y = x + b。那么对于在同一条45度直线的点,截距b是一定的,所以可以用y - x来代表某一条45度直线,所以可以另m = column - row。但是column可能会小于row,导致m为负值,所以可以将m增加n - 1让m变为正值,即m = n - 1 + column - row
  • 对于135度直线,可知斜率为-1,同理可知另m = column + row,此时不存在m为负值的情况,无须加n - 1
  • 不过需要注意的是flag_45和flag_135数组的大小是2 * n - 2,设置成2 * n即可
class Solution {
public:
    vector<vector<string>> solveNQueens(int n) {
        vector<vector<string>> res;
        vector<string> cur(n, string(n, '.'));
        vector<int> flag_col(n, 1), flag_45(2 * n, 1), flag_135(2 * n, 1);
        solveNQueens(n, 0, cur, res, flag_col, flag_45, flag_135);
        return res;
    }
private:
    void solveNQueens(int n, int row, vector<string>& cur, vector<vector<string>>& res, vector<int>& flag_col, vector<int>& flag_45, vector<int>& flag_135)
    {
        if(row >= n)
        {
            res.emplace_back(cur);
            return;
        }

        /* 回溯法 */
        for(int i = 0; i < n; ++i)
        {
            if(flag_col[i] && flag_45[n - 1 + i - row] && flag_135[i + row])
            {
                cur[row][i] = 'Q';
                flag_col[i] = flag_45[n - 1 + i - row] = flag_135[i + row] = 0;
                solveNQueens(n, row + 1, cur, res, flag_col, flag_45, flag_135);
                cur[row][i] = '.';
                flag_col[i] = flag_45[n - 1 + i - row] = flag_135[i + row] = 1;
            }
        }
    }
};
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/sinat_35261315/article/details/78542537
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-28 01:28:10
  • 阅读 ( 1216 )
  • 分类:算法

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢