C++实现LeetCode(52.N皇后问题之二)

 更新时间:2021年07月15日 17:06:03   作者:Grandyang  
这篇文章主要介绍了C++实现LeetCode(52.N皇后问题之二),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

[LeetCode] 52. N-Queens II N皇后问题之二

The n-queens puzzle is the problem of placing nqueens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return the number of distinct solutions to the n-queens puzzle.

Example:

Input: 4
Output: 2
Explanation: There are two distinct solutions to the 4-queens puzzle as shown below.
[
[".Q..",  // Solution 1
"...Q",
"Q...",
"..Q."],

 ["..Q.",  // Solution 2
"Q...",
"...Q",
".Q.."]
]

这道题是之前那道 N-Queens 的延伸,说是延伸其实我觉得两者顺序应该颠倒一样,上一道题比这道题还要稍稍复杂一些,两者本质上没有啥区别,都是要用回溯法 Backtracking 来解,如果理解了之前那道题的思路,此题只要做很小的改动即可,不再需要求出具体的皇后的摆法,只需要每次生成一种解法时,计数器加一即可,代码如下:

解法一:

class Solution {
public:
    int totalNQueens(int n) {
        int res = 0;
        vector<int> pos(n, -1);
        helper(pos, 0, res);
        return res;
    }
    void helper(vector<int>& pos, int row, int& res) {
        int n = pos.size();
        if (row == n) ++res;
        for (int col = 0; col < n; ++col) {
            if (isValid(pos, row, col)) {
                pos[row] = col;
                helper(pos, row + 1, res);
                pos[row] = -1;
            }
        }
    }
    bool isValid(vector<int>& pos, int row, int col) {
        for (int i = 0; i < row; ++i) {
            if (col == pos[i] || abs(row - i) == abs(col - pos[i])) {
                return false;
            }
        }
        return true;
    }
};

但是其实我们并不需要知道每一行皇后的具体位置,而只需要知道会不会产生冲突即可。对于每行要新加的位置,需要看跟之前的列,对角线,及逆对角线之间是否有冲突,所以我们需要三个布尔型数组,分别来记录之前的列 cols,对角线 diag,及逆对角线 anti_diag 上的位置,其中 cols 初始化大小为n,diag 和 anti_diag 均为 2n。列比较简单,是哪列就直接去 cols 中查找,而对角线的话,需要处理一下,如果我们仔细观察数组位置坐标的话,可以发现所有同一条主对角线的数,其纵坐标减去横坐标再加n,一定是相等的。同理,同一条逆对角线上的数字,其横纵坐标之和一定是相等的,根据这个,就可以快速判断主逆对角线上是否有冲突。任意一个有冲突的话,直接跳过当前位置,否则对于新位置,三个数组中对应位置都赋值为 true,然后对下一行调用递归,递归返回后记得还要还原状态,参见代码如下:

解法二:

class Solution {
public:
    int totalNQueens(int n) {
        int res = 0;
        vector<bool> cols(n), diag(2 * n), anti_diag(2 * n);
        helper(n, 0, cols, diag, anti_diag, res);
        return res;
    }
    void helper(int n, int row, vector<bool>& cols, vector<bool>& diag, vector<bool>& anti_diag, int& res) {
        if (row == n) ++res;
        for (int col = 0; col < n; ++col) {
            int idx1 = col - row + n, idx2 = col + row;
            if (cols[col] || diag[idx1] || anti_diag[idx2]) continue;
            cols[col] = diag[idx1] = anti_diag[idx2] = true;
            helper(n, row + 1, cols, diag, anti_diag, res);
            cols[col] = diag[idx1] = anti_diag[idx2] = false;
        }
    }
};

到此这篇关于C++实现LeetCode(52.N皇后问题之二)的文章就介绍到这了,更多相关C++实现N皇后问题之二内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈C++ IO流

    浅谈C++ IO流

    这篇文章主要介绍了C++ IO流的相关资料,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-08-08
  • c++基础语法:构造函数与析构函数

    c++基础语法:构造函数与析构函数

    构造函数用来构造一个对象,主要完成一些初始化工作,如果类中不提供构造函数,编译器会默认的提供一个默认构造函数(参数为空的构造函数就是默认构造函数) ;析构函数是隐式调用的,delete对象时候会自动调用完成对象的清理工作
    2013-09-09
  • C++实现简单酒店管理系统

    C++实现简单酒店管理系统

    这篇文章主要为大家详细介绍了C++实现简单酒店管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C语言 function recursion函数递归详解

    C语言 function recursion函数递归详解

    递归指的是在函数的定义中使用函数自身的方法,举个例子: 从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?"从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?"从前有座山,山里有座庙,循环下去
    2021-10-10
  • Pthread并发编程之线程基本元素和状态的剖析

    Pthread并发编程之线程基本元素和状态的剖析

    本篇文章主要给大家介绍pthread并发编程当中关于线程的基础概念,并且深入剖析进程的相关属性和设置,以及线程在内存当中的布局形式,帮助大家深刻理解线程
    2022-11-11
  • C++之CWnd窗口框架实例

    C++之CWnd窗口框架实例

    这篇文章主要介绍了C++之CWnd窗口框架,实例分析了CWnd窗口框架的结构,如构造函数、析构函数、消息映射函数等,需要的朋友可以参考下
    2014-10-10
  • Qt自定义美化滑动条

    Qt自定义美化滑动条

    这篇文章主要为大家详细介绍了Qt自定义美化滑动条的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-11-11
  • C++入门(命名空间,缺省参数,函数重载,引用,内联函数,auto,范围for)

    C++入门(命名空间,缺省参数,函数重载,引用,内联函数,auto,范围for)

    这篇文章主要介绍了C++入门(命名空间,缺省参数,函数重载,引用,内联函数,auto,范围for),这些基础知识是学习C++最最基础需要掌握的知识点,需要的朋友可以参考下
    2021-05-05
  • C语言实现经典扫雷游戏流程

    C语言实现经典扫雷游戏流程

    扫雷是电脑上很经典的游戏,特意去网上玩了一会,几次调试之后,发现这个比三子棋要复杂一些,尤其是空白展开算法上和堵截玩家有的一拼,与实际游戏差别较大,不能使用光标,下面来详解每一步分析
    2021-11-11
  • vscode+wsl运行编译c++的实现

    vscode+wsl运行编译c++的实现

    本文主要介绍了vscode+wsl运行编译c++的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-04-04

最新评论