【LeetCode算法系列题解】第51~55题

news2024/12/28 19:40:53

CONTENTS

    • LeetCode 51. N 皇后(困难)
    • LeetCode 52. N 皇后 II(困难)
    • LeetCode 53. 最大子序和(中等)
    • LeetCode 54. 螺旋矩阵(中等)
    • LeetCode 55. 跳跃游戏(中等)

LeetCode 51. N 皇后(困难)

【题目描述】

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
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 1\le n\le 9 1n9

【分析】


N 皇后裸题,DFS 爆搜每一行能放置皇后的位置即可,可以使用 col[i]dg[i] 以及 udg[i] 分别表示某一列、正对角线与反对角线是否能放皇后(由于我们是按行枚举的因此不用判断某一行是否可以放置)。由于正对角线为 y = x + b y=x+b y=x+b,因此可以用 y − x y-x yx 唯一确定一条正对角线(可以通过统一加上 n n n 避免越界);同理可以用 y + x y+x y+x 确定一条反对角线。


【代码】

class Solution {
public:
    vector<vector<string>> res;
    vector<bool> col, dg, udg;

    vector<vector<string>> solveNQueens(int n) {
        col = vector<bool>(n);
        dg = udg = vector<bool>(n << 1);  // 对角线的数量为2n-1
        vector<string> board(n, string(n, '.'));  // 初始化棋盘全为'.'
        dfs(board, 0);  // 从第0行开始搜
        return res;
    }

    void dfs(vector<string>& board, int x)
    {
        if (x == board.size()) { res.push_back(board); return; }
        for (int y = 0; y < board.size(); y++)
            if (!col[y] && !dg[y - x + board.size()] && !udg[y + x])
            {
                board[x][y] = 'Q';
                col[y] = dg[y - x + board.size()] = udg[y + x] = true;
                dfs(board, x + 1);
                col[y] = dg[y - x + board.size()] = udg[y + x] = false;
                board[x][y] = '.';
            }
    }
};

LeetCode 52. N 皇后 II(困难)

【题目描述】

N 皇后问题 研究的是如何将 n 个皇后放置在 n × n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n,返回 N 皇后问题不同的解决方案的数量。

【示例1】

在这里插入图片描述

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

【示例2】

输入:n = 1
输出:1

【提示】

1 ≤ n ≤ 9 1\le n\le 9 1n9

【分析】


与上一题一样,只需要记录方案数而不需要记录整个棋盘。


【代码】

class Solution {
public:
    vector<bool> col, dg, udg;

    int totalNQueens(int n) {
        col = vector<bool>(n);
        dg = udg = vector<bool>(n << 1);
        return dfs(n, 0);
    }

    int dfs(int n, int x)
    {
        if (x == n) return 1;
        int res = 0;
        for (int y = 0; y < n; y++)
            if (!col[y] && !dg[y - x + n] && !udg[y + x])
            {
                col[y] = dg[y - x + n] = udg[y + x] = true;
                res += dfs(n, x + 1);
                col[y] = dg[y - x + n] = udg[y + x] = false;
            }
        return res;
    }
};

LeetCode 53. 最大子序和(中等)

【题目描述】

给你一个整数数组 nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组是数组中的一个连续部分。

【示例1】

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

【示例2】

输入:nums = [1]
输出:1

【示例3】

输入:nums = [5,4,-1,7,8]
输出:23

【提示】

1 ≤ n u m s . l e n g t h ≤ 1 0 5 1\le nums.length\le 10^5 1nums.length105
− 1 0 4 ≤ n u m s [ i ] ≤ 1 0 4 -10^4\le nums[i]\le 10^4 104nums[i]104

【分析】


我们先分析 O ( n ) O(n) O(n) 的算法,用动态规划考虑:令 f[i] 表示所有以 nums[i] 结尾的区间中的最大和,那么状态转移有以下两种情况:

  • 区间长度等于1:f[i] = nums[i]
  • 区间长度大于1:f[i] = f[i - 1] + nums[i]

因此可以得到状态转移方程为:f[i] = max(nums[i], f[i - 1] + nums[i]) = nums[i] + max(0, f[i - 1]),由于 f[i] 只和 f[i - 1] 有关,因此我们可以只使用一个变量记录 f[i - 1] 的值即可。

现在我们考虑如何用分治法求解,其实分治法就是线段树维护动态最大字段和的简化版,当前数组的最大子段所在的区间可能有以下几种情况:

  • 在左子区间中,结果即为左子区间的最大子段;
  • 在右子区间中,结果即为右子区间的最大子段;
  • 横跨左右两个子区间,结果即为左子区间的最大后缀加上右子区间的最大前缀;

求解最大前缀与最大后缀时可能还会有以下几种情况:

  • 最大前缀横跨左右两个子区间,那么最大前缀为左子区间的总和加上右子区间的最大前缀;
  • 最大后缀横跨左右两个子区间,那么最大后缀为右子区间的总和加上左子区间的最大后缀;

因此我们需要处理出每个区间的最大子段、最大前缀、最大后缀以及总长度这四个信息。


【代码】

【动态规划实现】

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int res = INT_MIN;
        for (int i = 0, f = 0; i < nums.size(); i++)
            f = nums[i] + max(f, 0), res = max(res, f);
        return res;
    }
};

【分治法实现】

class Solution {
public:
    struct Node {
        int sum, lmax, rmax, tmax;  // 区间和,最大前缀,最大后缀,最大子段和
    };

    int maxSubArray(vector<int>& nums) {
        auto t = build(nums, 0, nums.size() - 1);
        return t.tmax;
    }

    Node build(vector<int>& nums, int l, int r)
    {
        if (l == r) return { nums[l], nums[l], nums[l], nums[l] };  // 递归到了长度为1的结点
        int mid = l + r >> 1;
        auto lnode = build(nums, l, mid), rnode = build(nums, mid + 1, r);
        // 线段树中的pushup操作
        Node res;
        res.sum = lnode.sum + rnode.sum;
        res.lmax = max(lnode.lmax, lnode.sum + rnode.lmax);
        res.rmax = max(rnode.rmax, rnode.sum + lnode.rmax);
        res.tmax = max(max(lnode.tmax, rnode.tmax), lnode.rmax + rnode.lmax);
        return res;
    }
};

LeetCode 54. 螺旋矩阵(中等)

【题目描述】

给你一个 mn 列的矩阵 matrix,请按照顺时针螺旋顺序,返回矩阵中的所有元素。

【示例1】

在这里插入图片描述

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

【示例2】

在这里插入图片描述

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

【提示】

m = = m a t r i x . l e n g t h m == matrix.length m==matrix.length
n = = m a t r i x [ i ] . l e n g t h n == matrix[i].length n==matrix[i].length
1 ≤ m , n ≤ 10 1\le m, n\le 10 1m,n10
− 100 ≤ m a t r i x [ i ] [ j ] ≤ 100 -100\le matrix[i][j]\le 100 100matrix[i][j]100

【分析】


分别设置向右、向下、向左、向上四个方向向量,然后模拟一遍即可,走出界或是已经遍历过了改变一下方向即可。


【代码】

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        int n = matrix.size(), m = matrix[0].size();
        int dx[] = { 0, 1, 0, -1 }, dy[] = { 1, 0, -1, 0 };
        vector<int> res;
        for (int i = 0, x = 0, y = 0, d = 0; i < n * m; i++)  // 总共遍历n*m个点
        {
            res.push_back(matrix[x][y]);
            matrix[x][y] = INT_MIN;  // 遍历过的数修改为INT_MIN
            int nx = x + dx[d], ny = y + dy[d];
            if (nx < 0 || nx >= n || ny < 0 || ny >= m || matrix[nx][ny] == INT_MIN) d = (d + 1) % 4;
            x += dx[d], y += dy[d];
        }
        return res;
    }
};

LeetCode 55. 跳跃游戏(中等)

【题目描述】

给你一个非负整数数组 nums,你最初位于数组的第一个下标。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true;否则,返回 false

【示例1】

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

【示例2】

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

【提示】

1 ≤ n u m s . l e n g t h ≤ 1 0 4 1\le nums.length\le 10^4 1nums.length104
0 ≤ n u m s [ i ] ≤ 1 0 5 0\le nums[i]\le 10^5 0nums[i]105

【分析】


本题和第45题差不多,我们从小到大枚举 i i i,并同时维护 i i i 之前所有点能跳到的最远距离 m a x _ d i s max\_dis max_dis,如果 max_dis < i,说明 i i i 之前没有点能够跳到 i i i 了,直接返回 false 即可。


【代码】

class Solution {
public:
    bool canJump(vector<int>& nums) {
        for (int i = 0, max_dis = 0; i < nums.size(); i++)
        {
            if (max_dis < i) return false;
            max_dis = max(max_dis, i + nums[i]);
        }
        return true;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/972537.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深入解析spring cloud gateway】07 自定义异常返回报文

Servlet的HttpResponse对象&#xff0c;返回响应报文&#xff0c;一般是这么写的&#xff0c;通过输出流直接就可以将返回报文输出。 OutputStream out response.getOutputStream(); out.write("输出的内容"); out.flush();在filter中如果发生异常&#xff08;例如…

如何使用GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图

GPT对于每个科研人员已经成为不可或缺的辅助工具&#xff0c;不同的研究领域和项目具有不同的需求。例如在科研编程、绘图领域&#xff1a; 1、编程建议和示例代码: 无论你使用的编程语言是Python、R、MATLAB还是其他语言&#xff0c;都可以为你提供相关的代码示例。 2、数据可…

TypeScript_树结构-BST树

树结构 树的特点 树通常有一个根。连接着根的是树干树干到上面之后会进行分叉成树枝&#xff0c;树枝还会分又成更小的树枝在树枝的最后是叶子 树的抽象 树可以模拟生活中的很多场景&#xff0c;比如&#xff1a;公司组织架构、家谱、DOM Tree、电脑文件夹架构 优秀的哈希函…

神策数据 CJO 系列丨解密 CJO:连接体验的下一个前沿趋势

10 余年前&#xff0c;市场营销的焦点聚集在增长黑客如何利用 AARRR 模型&#xff08;获取 Acquisition、激活 Activation、留存 Retention、收入 Revenue、传播 Referral&#xff09;来推动并加速企业的生长发展。我们曾相信&#xff0c;在 AARRR 漏斗中&#xff0c;只要我们吸…

宝塔面板定时监控和重启MySQL数据库(计划任务)

往期教程 如果还有不了解宝塔面板怎么使用的小伙伴&#xff0c;可以看下我总结的系列教程&#xff0c;保证从新手变老鸟&#xff1a; 【建站流程科普】 个人和企业搭建网站基本流程及六个主要步骤常见的VPS主机运维面板汇总—网站运维面板云服务器&#xff0c;VPS&#xff0…

76 # koa 上下文的实现原理

上一节实现了 koa 基本逻辑实现以及属性的扩展&#xff0c;下面继续实现上下文的实现 ctx 跟 proto 的关系 ctx.__proto__.__proto__ protoMDN&#xff1a;defineGetter 备注&#xff1a; 此特性已弃用&#xff0c;建议使用对象初始化语法或 Object.defineProperty() API 来…

《职场情绪稳定:内在的力量与策略》

近期发生的新闻热点&#xff0c;如大规模裁员、创业公司倒闭、公共卫生事件等&#xff0c;让公众更加关注稳定情绪和心理健康的问题。在职场中&#xff0c;我们常常遇到各种挑战和压力&#xff0c;如何保持稳定的情绪成了一个重要的话题。 首先&#xff0c;让我们分享一些工作中…

RecyclerView的smooth scroller -- 诸多案例

作者&#xff1a;snwrking 最近碰到好几个使用LinearSmoothScroll(下方简称为LSS)的场景, 让我对这个类的了解更加进一步, 所以分享在这, 希望对有需要的同学有所帮助. 我个人不太喜欢太理论的东西, 所以整篇文章几乎全是我做过的案例, 也方便也有类似需求的同学对号入座地取用…

【用unity实现100个游戏之8】用Unity制作一个炸弹人游戏

文章目录 前言素材开始一、绘制地图二、玩家设置三、玩家移动四、玩家四方向动画运动切换 五、放置炸弹六、生成爆炸效果七、墙壁和可破坏障碍物的判断八、道具生成和效果九、玩家死亡十、简单的敌人AI十一、虚拟摇杆 待续源码完结 前言 我们将在这个视频中&#xff0c;学习如…

Oracle 遍历变量游标

背景 由于我们的数据库系统中的游标特别多&#xff0c;DBA让我们优化&#xff0c;减少游标的使用。 电脑系统&#xff1a;windows数据库&#xff1a;Oracle数据库图形化界面工具&#xff1a;Toad&#xff0c;DBeaver(我測試的時候用的)记录日期&#xff1a;2023-09-04 具体实…

macbookpro怎么删除软件没有鼠标

macbookpro怎么删除软件没有鼠标,macbookpro触摸板可以替代鼠标进行操作。左右键功能与鼠标相同&#xff0c;可用于执行删除操作。此外&#xff0c;还可以利用键盘上的Delete键来删除选中的文件。 删除软件方法 方法1、打开应用程序&#xff0c;键盘按住control&#xff0c;加点…

解决微信小程序recycle-view使用百分比单位控制宽高时出现的内容溢出问题

recycle-view是微信小程序官方推出的一个经过优化的长列表组件&#xff0c;但是在使用百分比单位控制高宽时有个内容溢出问题&#xff0c;虽然它提供了height和width的参数可以设置宽高&#xff0c;但每次写列表都需要去js里获取宽高并设置是较为麻烦的&#xff0c;所以现在来着…

Vue 3 基础(二)基础 1

API 参考 1、创建一个 Vue 应用 1.1 应用实例 每个 Vue 应用都是通过 createApp 函数创建一个新的 应用实例&#xff1a; import { createApp } from vueconst app createApp({/* 根组件选项 */ })1.2 根组件 我们传入 createApp 的对象实际上是一个组件&#xff0c;每个…

uni-app 之 图片

uni-app 之 图片 获取图片 v-bind 动态绑定 image.png <template><view><view>--- 获取图片1 ---<image src"../../static/img/tabbar_home1.png"></image></view><view>--- 获取图片2 v-bind 动态绑定---<image v-bi…

SolVES4.1学习1——安装与使用教程

1、下载并安装 SolVES 4版本是QGIS插件&#xff0c;但实际使用过程中发现在最新版的QGIS安装该插件过程中&#xff0c;会报错或异常。因此需安装特定版本的软件。共需安装如下图软件及Java环境等。 根据官方文档安装好后&#xff0c;可以进行相关操作。 2、设置QGIS环境 QG…

AutoSAR配置与实践(基础篇)3.7 BSW的WatchDog功能(下)

AutoSAR配置与实践(基础篇)3.7 BSW的WatchDog功能(下) BSW的WatchDog功能(下)一、WDG和其他模块交互BSW的WatchDog功能(下) ->返回总目录<- 一、WDG和其他模块交互 模块交互 看门狗模块由WdgM统一管理,这里围绕WdgM模块分析与其他模块交互。通过交互的说明,可以…

css画箭头图标放标题前面,旋转,border的单个边框设置

CSS边框属性_css border dotted_小张biubiu的博客-CSDN博客 你还不知道css的旋转效果怎么实现&#xff1f;来这里看看吧_css旋转效果_我糖呢的博客-CSDN博客 .sub-title{position: relative;margin-left: 59px;& span{color: #1CDBFE;};& span::before{content: "…

MyBatis-Plus深入 —— 条件构造器与插件管理

前言 在前面的文章中&#xff0c;荔枝梳理了一个MyBatis-Plus的基本使用、配置和通用Service接口&#xff0c;我们发现在MyBatis-Plus的辅助增强下我们不再需要通过配置xml文件中的sql语句来实现基本的sql操作了&#xff0c;不愧是最佳搭档&#xff01;在这篇文章中&#xff0c…

ping: www.baidu.com: Name or service not known 写了DNS还是不行

环境描述&#xff1a;ESXI平台上&#xff0c;一台Centos7虚拟主机。 问题描述&#xff1a;平台上的其他的虚拟机可以正常ping通&#xff0c;就这台ping IP地址可以通&#xff0c;ping域名解析失败。 排查过程&#xff1a; 1、检查网卡配置文件和/etc/resolv.conf配置文件是否…