【LeetCode】升级打怪之路 Day 02:有序数组平方 滑动窗口法

今日题目:

  • 977. 有序数组的平方 | LeetCode
  • 209. 长度最小的子数组 | LeetCode
  • 76. 最小覆盖子串 | LeetCode
  • 59. 螺旋矩阵 II | LeetCode

目录

    • 今日总结
    • Problem 1:有序数组平方 ⭐⭐⭐
    • Problem 2:滑动窗口法 【必会】
      • LeetCode 209. 长度最小的子数组 Medium
      • LeetCode 76. 最小覆盖子串 Hard
    • Problem 3:螺旋矩阵 II 【还行】

今日总结

今天继续做的《数组》系列的题目,其中最重要的是学习滑动窗口法,学会了滑动窗口的代码框架思路,并借助两道题目来学习利用这个框架代码来解决具体问题,这是重点要掌握的。

除此之外,还解决了另外两道题,其中“有序数组平方”这道题锻炼了我对双指针法的灵活运行,学习到了在使用双指针时,选择一个好的行进方向可以避免对很多临界情况的判断,从而减少代码复杂度避免出错

Problem 1:有序数组平方 ⭐⭐⭐

977. 有序数组的平方 | LeetCode

这个题考验对“双指针”的灵活运用,不能死板。

最开始的做法是先找到第一个非负整数和最大负数,然后从中间向两边逐个比较得出结果,但这样的缺点是需要判断大量的临界条件,这很容易就产生错误,所以应该换一个思路。

在这里需要转换一个思路,不要从中间向两边走,而是从两边向中间走,从而利用双指针。这样在 while 中判断终止条件就只需要是 left 和 right 有没有碰上了。

这个题目最简单的方法就是,让 left 指向 0,right 指向末尾,然后两个指针逐渐向中间移动,每次将最大的放到结果集中:

class Solution {public int[] sortedSquares(int[] nums) {List<Integer> result = new ArrayList<>();int left = 0, right = nums.length - 1;while (!(left > right)) {  // 直到 left 和 right 碰上int leftValue = nums[left] * nums[left];int rightValue = nums[right] * nums[right];if (leftValue < rightValue) {result.add(rightValue);right--;} else {result.add(leftValue);left++;}}Collections.reverse(result);return result.stream().mapToInt(Integer::valueOf).toArray();}
}

因为这里是每次让平方值大的移动,当 left 或 right 走到中间绝对值是最小值的数字后就不会再移动了,所以不用担心 left 会超过负数范围或者 right 超过正数范围。我的一次 commit 就因为担心这个而多写了很多判断条件。

总结的经验是,利用好题目的特性和性质,选择好双指针的移动方向,尽量减少对临界条件的判断,从而减小代码复杂度

Problem 2:滑动窗口法 【必会】

这个方法是个通用的方法,用于解决子串问题

参考 labuladong 的讲解,滑动窗口的代码框架如下:

int left = 0, right = 0;while (left < right && right < s.size()) {// 增大窗口window.add(s[right]);right++;// 更新相关数据 ......while (window needs shrink) {// 缩小窗口(在这之前可能需要记录一下解)window.remove(s[left]);left++;// 更新相关数据 ......}
}

具体的讲解可以参考 labuladong 的文章。这里使用这个思路来解决 LeetCode 中 209 和 76 两个题目。重要是通过这几个题目来理解如何利用上面这个滑动窗口框架来解决具体的问题

LeetCode 209. 长度最小的子数组 Medium

209. 长度最小的子数组 | LeetCode

这个题可以经典地套用上面的框架,解题代码如下:

class Solution {public int minSubArrayLen(int target, int[] nums) {int low = 0, high = 0;int sum = 0;int minLen = nums.length;int curLen = 0;boolean found = false;while (high < nums.length) {// 扩大右窗口sum += nums[high];high++;// 更新相关数据curLen++;while (sum >= target) {// 记录解found = true;if (curLen < minLen) {minLen = curLen;}// 收缩左窗口sum -= nums[low];low++;// 更新相关数据curLen--;}}return found? minLen: 0;}
}

LeetCode 76. 最小覆盖子串 Hard

这个题虽然很难,但仍然能够套用上面介绍的滑动窗口框架,需要额外处理的就是一些条件的检查等问题。

通过这个题,可以很好地锻炼如何套用之前滑动窗口框架代码

关于这个题的讲解,可以参考 labuladong 文章中的讲解。

Problem 3:螺旋矩阵 II 【还行】

59. 螺旋矩阵 II | LeetCode

这个题目还行,比较偏技巧,抓住问题的要点:“方向的改变是固定的,也就是向右走的下一个方向一定是向下走”,所以我们需要确定好什么时候发生方向的转变。

这个题目在 LeetCode 中题解所介绍的有点麻烦,这里我的关键实现是实现一个 next() 函数,这个函数根据当前的方向和位置,确定出下一个走到的位置。确定下一个位置的思路是:判断一下当前方向能不能继续向下走,不能走的话就转变方向。

代码实现:

class Solution {int row;  // 当前位置的行号int col;  // 当前位置的列号int direction;  // 当前移动的方向public int[][] generateMatrix(int n) {row = 0;col = 0;direction = 1;int[][] matrix = new int[n][n];int square = n * n;for (int i = 1; i <= square; i++) {matrix[row][col] = i;if (i != square) {next(matrix, n);}}return matrix;}// 根据当前的方向和位置,确定下一个移动到的位置private boolean next(int[][] matrix, int n) {if (direction == 1) {  // 向右走if (col + 1 < n && matrix[row][col + 1] == 0) {  // 判断是否能继续按这个方向走col += 1;return true;} else {  // 不能继续的话,就转变方向direction = 2;return next(matrix, n);}}if (direction == 2) {  // 向下走if (row + 1 < n && matrix[row + 1][col] == 0) {row += 1;return true;} else {direction = 3;return next(matrix, n);}}if (direction == 3) {  // 向左走if (col - 1 >= 0 && matrix[row][col - 1] == 0) {col -= 1;return true;} else {direction = 4;return next(matrix, n);}}if (direction == 4) {  // 向上走if (row - 1 >= 0 && matrix[row - 1][col] == 0) {row -= 1;return true;} else {direction = 1;return next(matrix, n);}}return false;}}
  • 关键就是这里的 next() 函数的实现

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

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

相关文章

怎样提取WPS文档的目录?

怎样提取WPS文档的目录&#xff08;智能识别目录&#xff09;&#xff1f; 1. 将你的WPS文档打开&#xff0c;菜单&#xff1a;文件&#xff1a;输出为PDF&#xff0c;另存为(.pdf) 2. PyPDF2 从PDF文件中提取目录 运行 python pdf_read_dir.py 你的PDF文件 或者 java : pd…

【2024软件测试面试必会技能】Appium自动化(5):元素定位工具

常用元素定位工具使用 uiautomatorviewer定位工具&#xff1a; 元素定位主要用来获取元素信息&#xff0c;获取元素信息后才能用appium提供的相关API去识别和操作元素。 谷歌在AndroidSDK中&#xff0c;提供了元素定位工具uiautomatorviewer&#xff0c;该工具可在android-s…

系统学习Python——装饰器:类装饰器-[跟踪对象接口:基础知识]

分类目录&#xff1a;《系统学习Python》总目录 文章《系统学习Python——装饰器&#xff1a;类装饰器-[单例类&#xff1a;基础知识]》的单例示例阐明了如何使用类装饰器来管理一个类的所有实例。类装饰器的另一个常用场景是为每个生成的实例扩展接口。类装饰器基本上可以在实…

三opencv源码解压及环境变量配置

1.双击opencv-3.4.6-vc14-vc15.exe 2.选择解压的路径&#xff0c;点击【extract】 3.设计环境变量

从零学习Linux操作系统第二十七部分 shell脚本中的变量

一、什么是变量 变量的定义 定义本身 变量就是内存一片区域的地址 变量存在的意义 命令无法操作一直变化的目标 用一串固定的字符来表示不固定的目标可以解决此问题 二、变量的类型及命名规范 环境级别 export A1 在环境关闭后变量失效 退出后 关闭 用户级别&#xff…

《初阶数据结构》尾声

目录 前言&#xff1a; 《快速排序&#xff08;非递归&#xff09;》: 《归并排序》&#xff1a; 《归并排序&#xff08;非递归&#xff09;》&#xff1a; 《计数排序》&#xff1a; 对于快速排序的优化&#xff1a; 分析&#xff1a; 总结&#xff1a; 前言&#xff1a…

新疆营盘古城及古墓群安防舱体实施方案

3 总体布局 3.1设计原则 3.1.1执行有效的国家标准、国家军用标准和行业标准&#xff1b; 3.1.2满足指标要求&#xff1b; 3.1.3采用通用化、模块化设计&#xff0c;提高设备可维修性&#xff1b; 3.1.4采用人机工程学知识进行设计&#xff0c;充分考虑安全性。 3.2 总体…

Double-DQN算法

Double-DQN算法的原理简介、与DQN对比等。 参考深度Q网络进阶技巧 1. 原理简介 在DQN算法中&#xff0c;虽然有target_net和eval_net&#xff0c;但还是容易出现Q值高估的情况&#xff0c;原因在于训练时用通过target_net选取最优动作 a ⋆ argmax ⁡ a Q ( s t 1 , a ; w…

51单片机学习(3)-----独立按键控制LED的亮灭状态

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步了。 目录 一. 器件介绍及实验原理 1.独立按键 &#xff08;1&#xff09;独…

react 实现路由拦截

简单介绍下项目背景&#xff0c;我这里做了一个demo&#xff0c;前端使用mock数据&#xff0c;然后实现简单的路由拦截&#xff0c;校验session是否包含用户作为已登录的依据&#xff0c;react-router-dom是v6。不像vue可以设置登录拦截beforeenter&#xff0c;react需要我们自…

外包干了3个月,技术退步明显

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

Linux之用户和用户组的深入了解

目录 一、简介 1.1、用户&#xff1a; 1.2、用户组 1.3、UID和GID 1.3、用户账户分类 查看用户类别 超级用户root(0) 程序用户(1~499) 普通用户(500~65535) 二、用户 2.1、添加新的用户账号&#xff1a;useradd 2.2、删除账号&#xff1a;userdel 有-r与没有-r区别…

OSDI 2023: Hyrax Fail-in-Place Server Operation in Cloud Platforms

我们使用以下6个分类标准对本文的研究选题进行分析: 1. 硬件故障类型 DRAM: 此类别涉及研究如何处理内存相关的错误。这包括单比特错误,使用传统 ECC 进行校正,以及需要冗余、修复技术或隔离故障内存区域的更广泛的故障。磁盘: 此处研究将解决存储故障,尤其是 SSD 中的故障…

运维07:堡垒机

什么是跳板机 跳板机就是一台服务器而已&#xff0c;运维人员在使用管理服务器的时候&#xff0c;必须先连接上跳板机&#xff0c;然后才能去操控内网中的服务器&#xff0c;才能登录到目标设备上进行维护和操作 开发小张 ---> 登录跳板机 ---> 再登录开发服务器 测试…

贷齐乐系统最新版SQL注入(无需登录绕过WAF可union select跨表查询)

一、环境 已上传资源&#xff08;daiqile&#xff09; 二、代码解释 1.1Request 不管get请求还是post请求都可以接收到 1.2过滤的还挺多 1.3第二个WAF把数据分为两个了一个Key一个value&#xff0c;全是explode的功劳 1.4submit是if进入的前提 很明显走进来了 1.5那我们在这…

学习JAVA的第三天(基础)

目录 流程控制语句 顺序结构 分支结构 循环结构 分类&#xff1a; 练习 跳转控制语句 练习 数组 数组介绍 数组的定义和静态初始化 数组定义 数组的静态初始化 数组元素访问 数组遍历 数组动态初始化 JAVA内存分配 流程控制语句 顺序结构 是Java程序默认的执行流程…

UIKit 在 UICollectionView 中拖放交换 Cell 视图的极简实现

概览 UIKit 中的 UICollectionView 视图是我们显示多列集合数据的不二选择&#xff0c;而丰富多彩的交互操作更是我们选择 UICollectionView 视图的另一个重要原因。 如上图所示&#xff1a;我们实现了在 UICollectionView 中拖放交换任意两个 Cell 子视图的功能&#xff0c;这…

js如何判断一个对象中某一个属性存在并且有值

在JavaScript中&#xff0c;可以使用不同的方法来判断一个对象中某个属性是否存在并且有值。以下是几种常见的方法&#xff1a; 1、使用hasOwnProperty()方法&#xff1a;该方法用于检查对象是否具有指定的属性。可以通过以下方式来判断属性是否存在并且有值&#xff1a; if (…

整理了去年的一些运维面试题一

Ingress的yaml文件需要包含哪些&#xff1f; CICD搭建流程&#xff1f; JAVA程序打包工具&#xff1f; 如何检测Linux端口如何通信&#xff1f; k8s集群之间如何通信的&#xff1f; docker组成部分&#xff1f; 20位掩码有多少主机IP&#xff1f; 在linux中四个T的硬盘使用什…

Zabbix 远程监控主机

目录 1、安装 Zabbix 安装客户端 服务端测试通讯 Web页面添加主机 2、监控 Nginx 自定义脚本监控 Nginx web配置台 3、监控 MySQL 配置模版文件 配置Web界面 1、安装 Zabbix node-12 作为zabbix的被监控端&#xff0c;提供mysql服务器&#xff0c;配置zabbix监控node…