【寻找one piece的算法之路】——双指针算法!他与她是否会相遇呢?
💐个人主页:初晴~
📚相关专栏:寻找one piece的刷题之路
什么是双指针算法
双指针算法是一种常用的编程技巧,尤其在处理数组和字符串问题时非常有效。这种方法的核心思想是使用两个指针来遍历数据结构,这两个指针通常分别位于数据结构的起始位置或某些特定位置,通过移动这两个指针来达到解决问题的目的。双指针算法可以显著减少时间复杂度,使其从O(n2)O(n2)降低到O(n)O(n),甚至在某些情况下可以达到O(logn)O(logn)。
- 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。
- 对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循 环),也就是:
- left == right (两个指针指向同⼀个位置)
- left > right (两个指针错开)
一、复写零
题目链接
题目描述:
题目分析:
题目的意思就是遍历原数组,每遇到一次0,就将后面所有的数水平向右移动一位,并再插入一个0,最后仍丢弃溢出的数据,仍取原来的数组长度的数据。
分析:
我们先初始化两个指针 cur = 0 , dest = -1
判断 cur 位置的元素:◦ 如果是 0 的话, dest 往后移动两位;◦ 否则, dest 往后移动⼀位。
注意:
要判断 dest 是否越界到 n 的位置:如果越界,执⾏下⾯三步:
- n - 1 位置的值修改成 0 ;
- cur 向移动⼀步;
- dest 向前移动两步。
2.然后从后向前进⾏复写操作
从 cur 位置开始往前遍历原数组,依次还原出复写后的结果数组:
代码实现:
class Solution {public void duplicateZeros(int[] arr) {int len=arr.length,cur=0,dest=-1;while(cur<len){if(arr[cur]==0){dest+=2;}else{dest++;}if(dest==len-1)break;if(dest>len-1){arr[len-1]=0;cur--;dest=len-2;break;}cur++;}if(dest==cur)return;while(cur>=0){if(arr[cur]!=0){arr[dest--]=arr[cur--];}else{arr[dest--]=0;arr[dest--]=0;cur--;}}}
}
二、盛⽔最多的容器
题目描述:
题目分析:
v = (right - left) * min( height[right], height[left])
- 容器的宽度⼀定变⼩。
- 由于左边界较⼩,决定了⽔的⾼度。如果改变左边界,新的⽔⾯⾼度不确定,但是可能会超过原来左边界的柱⼦⾼度,因此容器的容积可能会增⼤。
- 如果改变右边界,⽆论右边界移动到哪⾥,新的⽔⾯的⾼度⼀定不会超过左边界,也就是不会超过现在的⽔⾯⾼度,但是由于容器的宽度减⼩,因此容器的容积⼀定会变⼩的。
- 当我们不断重复上述过程,每次都可以舍去⼤量不必要的枚举过程,直到 left 与 right 相遇。期间产⽣的所有的容积⾥⾯的最⼤值,就是最终答案。
代码实现:
class Solution {public int maxArea(int[] height) {int l=0,r=height.length-1,max=0,t;while(l<r){if(height[l]<height[r]){t=height[l]*(r-l);l++;}else{t=height[r]*(r-l);r--;}if(max<t)max=t;}return max;}
}
三、有效三⻆形的个数
题目链接
题目描述:
题目分析:
首先我们得知道,三条边能构成三角形的充要条件是:任意两边之和大于第三边。
不过事实上,我们只要保证两条短边和大于最长边即可。
因此,我们可以先将数组从小到大进行排序,接着用一个指针 j 固定一个「最⻓边」,然后在⽐这条边⼩的有序数组中找出⼀个⼆元组,使这个⼆元组之和⼤于这个最⻓边。由于数组是有序的,我们可以利⽤「对撞指针」来优化
设最⻓边枚举到 j 位置,区间 [left, right] 是 j 位置左边的区间(也就是⽐它⼩的区间):
- 如果 nums[left] + nums[right] > nums[i] :
说明 [left, right - 1] 区间上的所有元素均可以与 nums[right] 构成⽐ nums[j] ⼤的⼆元组
则满⾜条件的有 right - left 种
此时 right 位置的元素的所有情况相当于全部考虑完毕, right-- ,进⼊下⼀轮判断
- 如果 nums[left] + nums[right] <= nums[i] :
说明 left 位置的元素是不可能与 [left + 1, right] 位置上的元素构成满⾜条件的⼆元组
left 位置的元素可以舍去, left++ 进⼊下轮循环
代码实现:
class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int sum=0;for(int j=nums.length-1;j>=2;j--){int l=0,r=j-1;while(l<r){if(nums[l]+nums[r]>nums[j]){sum=sum+r-l;r--;}else{l++;}}}return sum;}
}
四、三数之和
题目链接
题目描述:
题目分析:
这题其实与上一题十分相似,都是要找一个满足一定条件的三元组,因此同样,我们可以采用先排序,接着用一个指针 j 固定一个数 a,接着在之后的区间内,利用双指针算法找到两数之和等于-a即可
需要注意的是,题目要求进行「去重」操作:
- 找到⼀个结果之后, left 和 right 指针要「跳过重复」的元素;
- 当使⽤完⼀次双指针算法之后,固定的 a 也要「跳过重复」的元素
代码实现:
class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> ans = new ArrayList<List<Integer>>();int n=nums.length;for(int j=0;j<n;){if(nums[j]>0)break;int l=j+1,r=n-1;int target=-nums[j];while(l<r){int sum=nums[l]+nums[r];if(sum==target){ans.add(new ArrayList<Integer>(Arrays.asList(nums[l],nums[r], nums[j])));if(nums[r]==nums[l])break;l++;r--;while(l<r&&nums[r+1]==nums[r])r--;while(l<r&&nums[l-1]==nums[l])l++;}else if(sum>target){r--;}else{l++; } }j++;while(j<n&&nums[j]==nums[j-1])j++;}return ans;}
}
五、四数之和
题目链接
题目描述:
题目描述:
这题的思想其实也与三数之和类似,我们只需要先排序,再用一个指针 i 固定一个数 a,在这个数 a 的后⾯区间上,利⽤「三数之和」找到三个数,使这三个数的和等于 target - a 即可
代码实现:
class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {int n=nums.length;long t,q;Arrays.sort(nums);List<List<Integer>> ans=new ArrayList<List<Integer>>();for(int i=0;i<n;){t=target;t-=nums[i];//if(t<0)return ans;for(int j=i+1;j<n;){q=t;q-=nums[j];int l=j+1,r=n-1;while(l<r){int sum=nums[l]+nums[r];if(sum==q){List<Integer> list=new ArrayList<Integer>();list.add(nums[i]);list.add(nums[j]);list.add(nums[l]);list.add(nums[r]);ans.add(list);l++;r--;while(l<r&&nums[l]==nums[l-1])l++;while(l<r&&nums[r]==nums[r+1])r--;}else if(sum>q)r--;else l++;}j++;while(j<n&&nums[j]==nums[j-1])j++;}i++;while(i<n&&nums[i]==nums[i-1])i++;}return ans;}
}
总结
双指针技巧的关键点:
- 初始化:通常一个指针指向序列的开始位置,另一个指针指向序列的结束位置或某个特定位置。
- 移动规则:根据问题的具体情况定义指针的移动规则,如当条件不满足时向前或向后移动。
- 更新状态:在每次移动指针之后更新当前的状态,如累加、记录最大值等。
- 退出条件:当两个指针相遇或某个指针超出界限时结束循环。
双指针算法是一种简单而有效的算法技巧,通过维护两个指针的状态来简化问题的复杂度。合理地运用双指针法,可以帮助我们在处理数组和字符串问题时更加高效地达成目标。
那么本篇文章就到此为止了,如果觉得这篇文章对你有帮助的话,可以点一下关注和点赞来支持作者哦。如果有什么讲的不对的地方欢迎在评论区指出,希望能够和你们一起进步✊
相关文章:

【寻找one piece的算法之路】——双指针算法!他与她是否会相遇呢?
💐个人主页:初晴~ 📚相关专栏:寻找one piece的刷题之路 什么是双指针算法 双指针算法是一种常用的编程技巧,尤其在处理数组和字符串问题时非常有效。这种方法的核心思想是使用两个指针来遍历数据结构,这两…...

UFS 3.1架构简介
整个UFS协议栈可以分为三层:应用层(UFS Application Layer(UAP)),传输层(UFS Transport Layer(UTP)),链路层(UIC InterConnect Layer(UIC))。应用层发出SCSI命令(UFS没有自己的命令使用的是简化的SCSI命令),在传输层将SCSI分装为UPIU,再经过链路层将命令发送给Devices。下…...

注册安全分析报告:科研诚信查询平台无验证方式导致安全隐患
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…...
04.useTitle
在 React 应用中,动态更新页面标题是提升用户体验的一个重要方面。它可以让用户更清楚地知道当前页面的内容或状态,特别是在单页应用(SPA)中。useTitle 钩子提供了一种简单而有效的方式来管理文档标题。以下是如何实现和使用这个自定义钩子: const useTitle = title =>…...
ROS2中的srv、action、发布订阅三种方式
ROS2中的srv、action、发布订阅三种方式 以下是ROS2中srv、action、发布订阅三种方式的差异和使用场景的表格形式呈现: 特性/方式srv(服务)action(动作)发布订阅(Publish-Subscribe)通信模式请…...

HarmonyOS/OpenHarmony 自定义弹窗页面级层级控制解决方案
关键词:CuntomDialog自定义弹窗、SubWindow子窗口、页面级、弹窗层级控制、鸿蒙、弹窗展示层级异常 问题存在API版本:API10 - API12(该问题已反馈,期望后续官方能增加页面级控制能力) 在正常的鸿蒙app开发过程中&…...

C/C++进阶(一)--内存管理
更多精彩内容..... 🎉❤️播主の主页✨😘 Stark、-CSDN博客 本文所在专栏: 学习专栏C语言_Stark、的博客-CSDN博客 其它专栏: 数据结构与算法_Stark、的博客-CSDN博客 项目实战C系列_Stark、的博客-CSDN博客 座右铭&a…...

docker-compose 快速部署clickhouse集群
在本教程中,我们将学习如何使用 Docker Compose 部署一个带有三节点的 ClickHouse 集群,并使用 ZooKeeper 作为分布式协调服务。 前提条件 注意事项: 镜像版本号注意保持一致 [zookeeper:3.7, clickhouse/clickhouse-server:22.5.4]config…...

闯关训练三:Git 基础知识
任务1: 破冰活动:自我介绍 点击Fork目标项目,创建一个新的Fork 获取仓库链接 在连接好开发机的vscode终端中逐行执行以下代码: git clone https://github.com/KelvinIII/Tutorial.git # 修改为自己frok的仓库 cd Tutorial/ git branch -a g…...

Java--IO基本流
IO流 概述 生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrls ,可能文件就白白编辑了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘…...
结合大语言模型的机械臂抓取操作简单介绍
一、大语言模型与机械臂抓取的基本操作 1. 大语言模型简介 大语言模型是基于深度学习技术构建的自然语言处理模型,能够生成、理解和处理文本信息。这些模型通过训练大量的文本数据,学习语法、上下文和常识,能够执行多种任务,如文…...

Vivado - BD(差分时钟、简单分频、RESET、KEY)
目录 1. 简介 1.1 要点 1.2 buffer 介绍 2. vivado 工程 2.1 Block Design 2.2 IBUFDS 2.3 BUFGCE_DIV 2.4 Processor System Reset 2.5 key_mod 2.6 led_drv 3. 编译与调试 3.1 XDC 3.2 Debug 4. 总结 1. 简介 1.1 要点 了解 Utility Buffer v2.2 中的 Buffer…...

7--苍穹外卖-SpringBoot项目中套餐管理 详解(一)
前言 目录 新增套餐 需求分析和设计 代码开发 根据分类id查询菜品 Controller层 Service层 ServiceImpl层 Mapper层 DishMapper.xml 新增套餐 实体类 mapper层 Service层 ServiceImpl层 Mapper层 SetmealMapper.xml setmealDishMapper.xml 套餐分页查询 需求分…...
【尚硅谷】RocketMQ 消息队列学习笔记
RocketMQ 和 Kafka 消息队列概念比较? 好的!RocketMQ 和 Kafka 都是分布式消息队列系统,它们的核心概念有很多相似之处,但在具体实现和命名上有所不同。下面我通过一个表格来对比 RocketMQ 和 Kafka 中的五个概念:消息…...

C题(三)芝麻开门 --- strcmp函数应用
场景一:“芝麻开门 ”是通往C语言的大门的暗号,现在你需要说对暗号,大门才会打开。 【分解目标1】字符串的输入 char arr[20] { 0 }; //字符的集合---字符串(数组表示)//20为预定的数组的大小scanf("%s", a…...

C++函数模板、选择排序实现(从大到小)
template <class T> void mysw (T &a , T &b) {T temp b;b a;a temp; }template <class T> void muSort( T &arr ,int len) {//该实现为选择排序(高到低)for (int i 0; i < len; i) {int max i ; //首先默认本次循环首位元素为最大for (int j …...

EasyExcel使用介绍
EasyExcel使用 1、EasyExcel介绍 1.1 官网介绍 传统操作Excel大多都是利用Apach POI进行操作的,但是POI框架并不完善,使用过程非常繁琐且有较多的缺陷: 动态操作Excel非常繁琐,对于新手来说,很难在短时间内上手;读写时需要占用…...
字段临时缓存包装器
前言 在实际开发中,我们有时候存在一种需求,例如对于某个字段,我们希望在某个明确的保存节点前对字段的修改都仅作为缓存保留,最终是否应用这些修改取决于某些条件,比如玩家对游戏设置的修改可能需要玩家明确确认应用修…...

Python(三)——列表
文章目录 创建列表访问下标遍历列表元素新增元素查找元素删除元素连接列表切片操作 创建列表 创建列表主要有两种方式 [ ]表示一个空的列表 a [] print(type(a)) # <class list> print(a) # []通过list()的方式来创建一个空列表 a list() print(type(a)) # …...

MySQL--三大范式(超详解)
目录 一、前言二、三大范式2.1概念2.2第一范式(1NF)2.3第二范式(2NF)2.3第三范式(3NF) 一、前言 欢迎大家来到权权的博客~欢迎大家对我的博客进行指导,有什么不对的地方,我会及时改进…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...