zoukankan      html  css  js  c++  java
  • 【LeetCode】N皇后I

    【问题】n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

    给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
    每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

    示例:
    
    输入: 4
    输出:
    [[".Q..", // 解法 1
    "…Q",
    "Q…",
    "..Q."],
    ["..Q.", // 解法 2
    "Q…",
    "…Q",
    ".Q.."]
    ]
    解释: 4 皇后问题存在两个不同的解法。

    【思路】N皇后在不同地方,不同场合都有听到过这个问题,但仔细分析了一下,发现和原来的数独问题十分的类似,也是约束编程+回溯法的思想!我们首先分析一下两者的相同点和不同点:

    解数独问题:

    N确定,为9x9的网格,约束条件为:向未知位置填入1-9的数字,使得该数所在的行和列均不重复以及所在的3x3网格内也不重复,因此我们需要使用col_[9][9]、row_[9][9]、block_[9][9]来储存数字在行、列和网格中是否被使用过。使用过标记为true,否则标记为false。

    N皇后问题:

    N不确定,因此我们需要在函数中建立辅助空间,而不能建立成成员变量,约束条件为:在NxN的网格中任意摆放皇后Q,为了避免皇后之间不能相互攻击,该位置所在的行、列以及主、副对角线均只能有这一个Q,因此我们需要使用cols_标记每一列是否存在Q,使用diag1s_、diag2s_来标记主、副对角线是否存在Q。

    当了解到这些之后,整个回溯递归方法就十分清晰了,中间有一个地方十分让人困惑,ll和rr是如何求解的呢?这就要说到主、副对角线的性质了!!!

    • 主对角线:col+row的值是一定的,范围[0, 2n-2],从零开始

    • 副对角线:col-row的值是一定的,为了使索引有效,加上定值n-1, 最终范围[0, 2n-2]

    有人会问,row怎么遍历,emmm, 递归修改的参数就是row,其实也就相当于遍历了整个网格,但速度还可以,中间存在了很多条件判断进行剪枝!

    class Solution {
    public:
        void solve(vector<vector<string>>& res, vector<string>& tmp, vector<bool>& cols_, vector<bool>& diag1s_, vector<bool>& diag2s_, int n, int row){
            if(row == n){
                res.push_back(tmp);
                return;
            }
            for(auto col = 0; col < n; col++){
                int ll = row + col;
                int rr = row - col + n - 1;
                if (cols_[col] && diag1s_[ll] && diag2s_[rr]){
                    tmp[row][col] = 'Q';
                    cols_[col] = false;
                    diag1s_[ll] = false;
                    diag2s_[rr] = false;
    
                    solve(res, tmp, cols_, diag1s_, diag2s_, n, row+1);
    
                    tmp[row][col] = '.';
                    cols_[col] = true;
                    diag1s_[ll] = true;
                    diag2s_[rr] = true;
                }
            }
        }
    
        vector<vector<string>> solveNQueens(int n) {
            vector<vector<string>> res;
            vector<string> tmp(n, string(n, '.'));
            vector<bool> cols_(n, true);
            vector<bool> diag1s_(2*n-1, true);
            vector<bool> diag2s_(2*n-1, true);
            solve(res, tmp, cols_, diag1s_, diag2s_, n, 0);
            return res;
        }
    
    };
  • 相关阅读:
    IDirect3DDevice9::Clear
    Width vs Pitch
    5- vue django restful framework 打造生鲜超市 -完成商品列表页(上)
    4- vue django restful framework 打造生鲜超市 -restful api 与前端源码介绍
    3- vue django restful framework 打造生鲜超市
    2- vue django restful framework 打造生鲜超市 -环境搭建
    1- vue django restful framework 打造生鲜超市
    Scrapy分布式爬虫打造搜索引擎- (二)伯乐在线爬取所有文章
    windows10上安装mysql
    博客开通第一天
  • 原文地址:https://www.cnblogs.com/zhudingtop/p/11650924.html
Copyright © 2011-2022 走看看