首页 > 其他分享 >力扣51. N 皇后(回溯法)

力扣51. N 皇后(回溯法)

时间:2023-01-11 17:25:19浏览次数:47  
标签:... 遍历 int 对角线 51 力扣 回溯 皇后

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

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

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

示例 1:

输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

 

示例 2:

输入:n = 1
输出:[["Q"]]

 

提示:

  • 1 <= n <= 9

经典的回溯法问题,类似的需要回溯法的还有排列组合问题,一般是DFS+回溯来实现一个暴力搜索。

N皇后问题的有两个核心,一个是回溯,一个是对4个限定条件的判断(行、列、两条对角线)

1.回溯核心逻辑

void backtracking(element length,element end,element result,element set,int startIndex,...)
{
    if(终止条件==end){
        result.add(set);  //将当前集合加到结果集中
    for(i=startIndex;i<length;++i){
        更新当前集合set;
        backtracking(length,end,result,set,...);  //往下一层遍历
        还原当前集合set;
    }
}

2.由于棋盘每行每列都会有一个皇后,我们可以选择一行一行确定或者一列一列遍历,这边我选择一行一行遍历。如果一行一行遍历,那么我们在遍历的过程中只需要记录列的皇后放置信息(因为每行放置了皇后之后就会进入下一层遍历,不会在该层停留,即已经确保了同一行只有一个皇后)、主对角线、副对角线的信息。

(0,0) (0,1) (0,2) (0,3)
(1,0) (1,1) (1,2) (1,3)
(2,0) (2,1) (2,2) (2,3)
(3,0) (3,1) (3,2) (3,3)

在一个棋盘上,假设某点坐标为( i , j )我们可以明显看出同一主对角线上i - j的值相同(注意不是|i - j|相同),同一副对角线上的i + j相同,据此我们可以用三个数组来快速判断某个位置能不能放入皇后。

 

 1 class Solution {
 2 public:
 3     vector<int> column,ldiagonal,rdiagonal;
 4     vector<vector<string>> result;
 5     void backtracking(int n,vector<string> mmap,int row){
 6         if (row==n){  //棋盘内已有n个皇后
 7             result.push_back(mmap);
 8             return;
 9         }
10 
11         for (int j=0;j<n;++j){
12             if (column[j]==0&&ldiagonal[row+j]==0&&rdiagonal[row-j+n-1]==0){
13                 // cout<<row<<" and "<<j<<endl;
14                 // cout<<row-j+n-1<<" "<<abs(row-j)<<endl;
15                 mmap[row][j]='Q';
16                 column[j]=1;
17                 ldiagonal[row+j]=1;
18                 rdiagonal[row-j+n-1]=1;
19                 backtracking(n,mmap,row+1);
20                 //回溯
21                 rdiagonal[row-j+n-1]=0;
22                 ldiagonal[row+j]=0;
23                 column[j]=0;
24                 mmap[row][j]='.';
25             }
26         }
27         return;
28     }
29     vector<vector<string>> solveNQueens(int n) {
30         //初始化
31         vector<string> initial;
32         for (int i=0;i<n;++i){
33             string temp;
34             for (int j=0;j<n;++j){
35                 temp.push_back('.');
36             }
37             initial.push_back(temp);
38         }
39         for (int i=0;i<25;++i){
40             column.push_back(0);
41             rdiagonal.push_back(0);
42             ldiagonal.push_back(0);
43         }
44 
45         backtracking(n,initial,0);
46 
47         return result;
48     }
49 };

 

标签:...,遍历,int,对角线,51,力扣,回溯,皇后
From: https://www.cnblogs.com/coderhrz/p/17044381.html

相关文章

  • CVE-2020-2551
    前言2020年1月15日,Oracle发布了一系列的安全补丁,其中OracleWebLogicServer产品有高危漏洞,漏洞编号CVE-2020-2551,CVSS评分9.8分,漏洞利用难度低,可基于IIOP协议执行......
  • 数字秒表+普中51单片机+江科大自化协
    1系统框图 2实验现象 3参考程序3.1主程序#include<REGX52.H>#include"timer0.h"#include"key.h"#include"Nixie.h"#include"delayms.h"#include......
  • C51单片机开发环境
    C51单片机开发环境0OS环境1IDE下载Clion2嵌入式插件安装pio插件3嵌入式安装PlatformIOCore我使用的是HomeBrew进行管理brewupdatebrewinstallpl......
  • day1---二分查找打卡---力扣704--力扣27
     打卡第一天,希望自己可以坚持两个月,把算法能力提升去,然后方便找工作。然后很久没有刷算法题目了,这次的态度要很端正,因为之前刷题目的过程都不是一个非常完整的过程,所以......
  • 力扣 295. 数据流的中位数[堆]
    295.数据流的中位数中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。例如 arr=[2,3,4] 的中位数是 3 。......
  • CapStone/CS5518芯片,MIPI转双通道LVDS可pin√pin替代国腾GM877
    GM8775C型DSI转双通道LVDS发送器产品主要实现将MIPIDSI转单/双通道LVDS功能,MIPI支持1/2/3/4通道可选,最大支持4Gbps速率。LVDS时钟频率最高154MHz,最大支持视......
  • 力扣102 二叉树的层序遍历(广度优先搜索)
    题目:给你二叉树的根节点root,返回其节点值的层序遍历。(即逐层地,从左到右访问所有节点)。示例:输入:root=[3,9,20,null,null,15,7]输出:[[3],[9,20],[15,7]]思......
  • 力扣226 翻转二叉树
    题目:给你一棵二叉树的根节点root,翻转这棵二叉树,并返回其根节点。示例:输入:root=[4,2,7,1,3,6,9]输出:[4,7,2,9,6,3,1] ......
  • CodeForces - 510C Fox And Names
    CodeForces-510CFoxAndNames题解:建图+拓扑排序首先题目想让你按照给定的字符串修改字母表的字母序,我们很容易想到拓扑排序,但是这怎么建图?实际上对于两个输入的字......
  • 力扣刷题——day1
    1、两数之和一下就能想到暴力解法,就是一个两个遍历。classSolution{publicint[]twoSum(int[]nums,inttarget){int[]sum=newint[2];......