算法思想总结:双指针算法
一、移动零
. - 力扣(LeetCode) 移动零

该题重要信息:1、保持非0元素的相对位置。2、原地对数组进行操作
思路:双指针算法

class Solution {
public:void moveZeroes(vector<int>& nums){int n=nums.size();for(int cur=0,des=-1;cur<n;++cur)if(nums[cur])//如为非零,就要与des后面的位置元素进行交换swap(nums[++des],nums[cur]);}
};
二、复写零
. - 力扣(LeetCode)复写零

该题的重要信息:1、不要在超过该数组的长度的位置写入元素(就是不要越界)2、就地修改(就是不能创建新数组)。3、不返回任何东西。
思路:双指针算法

class Solution {
public:void duplicateZeros(vector<int>& arr){int cur=0,des=-1,n=arr.size();//找最后一个被复写数的位置for(;cur<n;++cur){if(arr[cur])++des;elsedes+=2;if(des>=n-1)//要让des指向最后一个位置break;}//边界修正if(des==n){arr[--des]=0;--des;--cur;}//从后往前复写for(;cur>=0;--cur){if(arr[cur])arr[des--]=arr[cur];else{arr[des--]=0;arr[des--]=0;}}}
};
三、快乐数
. - 力扣(LeetCode)快乐数

该题的关键是:将正整数变成他的每位数的平方之和,有可能会一直循环始终到不了1,也有始终是1(快乐数)
思路:快慢双指针算法

以上的两个结论在博主的关于链表带环追击问题的文章里面有分析
顺序表、链表相关OJ题(2)-CSDN博客
class Solution {
public:int bitsum(int n){ int sum=0;while(n){int t=n%10;sum+=t*t;n/=10;//最后一位算完后拿掉}return sum;}bool isHappy(int n) {int slow=n,fast=bitsum(n);while(fast!=slow){slow=bitsum(slow);fast=bitsum(bitsum(fast));}return slow==1;}
};
四、盛最多水的容器
. - 力扣(LeetCode)盛最多水的容器

思路1、暴力枚举(时间复杂度太高)

class Solution {
public:int maxArea(vector<int>& height){//暴力枚举int n=height.size();int ret=0;for(int i=0;i<n;++i)for(int j=i+1;j<n;++j)ret=max(ret,min(height[i],height[j])*(j-i));return ret;}
};

思路2、双指针对撞算法

class Solution {
public:int maxArea(vector<int>& height){int left=0,right=height.size()-1,ret=0;while(left<right){ret=max(ret,min(height[left],height[right])*(right-left));if(height[left]<height[right])++left;else--right;}return ret;}
};
五、有效三角形的个数
. - 力扣(LeetCode)有效三角形的个数

思路1:升序+暴力枚举
思路2:升序+利用双指针算法

class Solution {
public:int triangleNumber(vector<int>& nums) {//排序一下sort(nums.begin(),nums.end());//先固定一个数,然后用双指针去找比较小的两个数int n=nums.size(),ret=0;for(int i=n-1;i>=2;--i){int left=0,right=i-1;while(left<right){int sum=nums[left]+nums[right];if(sum<=nums[i]) ++left;else {ret+=(right-left);--right;} }}return ret;}
};
六、查找总价格为目标值的两个商品
. - 力扣(LeetCode)查找总价格为目标值的两个商品

思路1:两层for循环找到所有组合去计算
思路2:利用单调性,使用双指针算法解决问题

class Solution {
public:vector<int> twoSum(vector<int>& price, int target) {int n=price.size();int left=0,right=n-1;while(left<right){int sum=price[left]+price[right];if(sum>target) --right;else if(sum<target) ++left;else return {price[left],price[right]};}return {1,0};}
};
七、三数之和
. - 力扣(LeetCode)三数之和

解法1:排序+暴力枚举+set去重
解法2:排序+双指针

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums){vector<vector<int>> ret;int n=nums.size();//先排序sort(nums.begin(),nums.end());//先固定一个数for(int i=0;i<n;){if(nums[i]>0) break;//小优化int target =-nums[i];//目标值//定义双指针int left=i+1,right=n-1;while(left<right){int sum=nums[left]+nums[right];if(sum<target) ++left;else if(sum>target) --right;else {ret.push_back({nums[left],nums[right],nums[i]});//插入进去++left;--right;//去重while(left<right&&nums[left]==nums[left-1]) ++left;//去重要注意边界while(left<right&&nums[right]==nums[right+1]) --right;}}++i;while(i<n&&nums[i]==nums[i-1]) ++i;//去重要注意边界}return ret;}
};
八、四数之和
. - 力扣(LeetCode)四数之和

解法1:排序+暴力枚举+set去重
解法2:排序+双指针(和上一题基本一样,无非就是多固定了一个数)

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ret;//先进行排序sort(nums.begin(),nums.end());//利用双指针解决int n=nums.size();//先固定一个数for(int i=0;i<n;){//再固定一个数for(int j=i+1;j<n;){int left=j+1,right=n-1;long long aim=(long long)target-nums[i]-nums[j];//确保不超出范围while(left<right){long long sum=nums[left]+nums[right];if(sum<aim) ++left;else if(sum>aim) --right;else {ret.push_back({nums[i],nums[j],nums[left],nums[right]});++left;--right;//去重while(left<right&&nums[left]==nums[left-1]) ++left;while(left<right&&nums[right]==nums[right+1]) --right;}}//去重++j;while(j<n&&nums[j]==nums[j-1]) ++j;}//去重++i;while(i<n&&nums[i]==nums[i-1]) ++i;}return ret;}
};
九、总结
常见的双指针有三种形式:前后指针、对撞指针、快慢指针
1、前后指针:用于顺序结构,一般是两个指针同方向,cur指针用来遍历数组,des指针将数组进行区域划分。(如1、2题)
注意事项:如果是从前往后遍历,要注意dst不能走得太快,否则cur还没遍历到一些数就会被覆盖掉,必要时候可以根据情况从后往前遍历。
2、快慢指针:其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。
这种⽅法对于处理环形链表或数组⾮常有⽤。(如第3题,以及链表带环的问题)
注意事项: 其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。最常用的就是快指针走两步,慢指针走一步。
3、对撞指针:一般用于顺序结构。从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。并且常常会用到单调性!!(如4-8题)
注意事项:对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环)
用双指针策略一般可以比暴力枚举降低一个次方的时间复杂度
如果后面还有关双指针的经典题目,博主会继续在这篇更新的!!

相关文章:
算法思想总结:双指针算法
一、移动零 . - 力扣(LeetCode) 移动零 该题重要信息:1、保持非0元素的相对位置。2、原地对数组进行操作 思路:双指针算法 class Solution { public:void moveZeroes(vector<int>& nums){int nnums.size();for(int cur…...
python中的zip函数
1.zip()同时迭代多个列表、字典等 使用zip()可以同时迭代多个可迭代对象,如列表、字典。 注意:当若干个可迭代对象的长度不相等时,zip()函数会停止在最短的可迭代对象。 例子: # 定义可迭代对象 numbers …...
Element 选择季度组件
<template><el-dialogtitle"选择季度":show-close"false":close-on-click-modal"false":close-on-press-escape"false":visible"visiable"class"dialog list"append-to-body><div><div>&…...
4.MongoDB中16个常用CURD
基本的CURD 作为一个非专业的DBA,我们只需要会一些基本的curd就行,专业的内容还是需要专业的人去干的。CRUD 也就是增删改查,这是数据库最基本的功能,查询还支持全文检索,GEO 地理位置查询等。 01创建库 无需单独创…...
Tomcat数据源笔记
Tomcat数据源笔记 连接池的概念 连接池是一种由容器提供的机制,用于管理数据库连接对象的集合。连接池的主要作用是在应用程序需要与数据库进行交互时,提供可复用的连接对象,从而减少每次建立数据库连接的开销。 连接池的工作原理 连接池的…...
Spring-Kafka笔记整理
引入依赖<dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency>配置application.propertiesspring.kafka.bootstrap-servers192.168.99.51:9092编写kafka的配置类Configuration …...
已解决org.apache.hadoop.hdfs.protocol.QuotaExceededException异常的正确解决方法,亲测有效!!!
已解决org.apache.hadoop.hdfs.protocol.QuotaExceededException异常的正确解决方法,亲测有效!!! 目录 问题分析 报错原因 解决思路 解决方法 总结 博主v:XiaoMing_Java 问题分析 在使用Hadoop分布式文件系统&a…...
GitHub打不开的解决方案(超简单)
在国内,github官网经常面临打不开或访问极慢的问题,不挂VPN(梯子,飞机,魔法)使用体验极差,那有什么好办法解决github官网访问不了的问题?今天小布教你几招轻松访问github官网。 git…...
Unity开发一个FPS游戏之二
在之前的文章中,我介绍了如何开发一个FPS游戏,添加一个第一人称的主角,并设置武器。现在我将继续完善这个游戏,打算添加敌人,实现其智能寻找玩家并进行对抗。完成的效果如下: fps_enemy_demo 下载资源 首先是设计敌人,我们可以在网上找到一些好的免费素材,例如在Unity…...
STM32F103 CubeMX 使用USB生成鼠标设备
STM32F103 CubeMX 使用USB生成鼠标设备 1 配置cubeMX1.1配置外部晶振,配置debug口1.2 配置USB1.3 配置芯片的时钟1.4 生成工程 2. 编写代码2.1 添加申明2.2 main函数代码 1 配置cubeMX 1.1配置外部晶振,配置debug口 1.2 配置USB 1.3 配置芯片的时钟 需…...
HJXH-E1/U静态信号继电器 面板安装 辅助电源220VDC 启动电压220VDC JOSEF约瑟
HJXH系列静态信号继电器 HJXH-61/U静态信号继电器; HJXH-61/I静态信号继电器; HJXH-62/U静态信号继电器; HJXH-62/I静态信号继电器; HJXH-E1/U静态信号继电器; HJXH-E1/I静态信号继电器; HJXH-E2/U静态信号…...
SpringBoot3下Kafka分组均衡消费实现
首先添加maven依赖: <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><version>2.8.11</version><exclusions><!--此处一定要排除kafka-clients,然…...
鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:GridItem)
网格容器中单项内容容器。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。仅支持作为Grid组件的子组件使用。 子组件 可以包含单个子组件。 接口 GridItem GridItem(value?: GridItemOptions)…...
Qt 使用RAW INPUT获取HID触摸屏,笔设备,鼠标的原始数据,最低受支持的客户端:Windows XP [仅限桌面应用]
在开发绘图应用程序时,经常会需要读取笔设备的数据,通过对笔数据的解析,来判断笔的坐标,粗细。如果仅仅只是读取鼠标的坐标,就需要人为在应用程序端去修改笔的粗细,并且使用体验不好,如果可以实…...
easyexcel导出excel文件到s3服务器
导出excel文件是开发中常见的需求 常见的做法一般是直接通过请求接口响应对象HttpServletResponse把文件输出 我们可以使用原生的poi工具类操作.也可以使用easypoi.easyexcel等基于poi二次封装的工具处理 下面是代码 /*** 导出列表** param request* param response*/Overri…...
xss.haozi.me靶场“0x0B-0x12”通关教程
君衍. 一、0x0B 实体编码绕过二、0x0C script绕过三、0x0D 注释绕过四、0X0E ſ符号绕过五、0x0F 编码解码六、0x10 直接执行七、0x11 闭合绕过八、0x12 闭合绕过 XSS-Labs靶场“1-5”关通关教程 XSS-Labs靶场“6-10”关通关教程 Appcms存储型XSS漏洞复现 XSS-Labs靶场“11-13、…...
linux--redhat系统Yum源配置
1)说明 redhat yum命令使用报错解决-重新配置yum源 解决--更改yum源 2)更改yum源 (1)进入源目录 cd /etc/yum.repos.d/ (2)备份 redhat 默认源 mv redhat.repo redhat.repo-bak (3)…...
el-Switch 开关二次确认
前言 最近在做毕设,有个需求是点击按钮控制用户的状态是否禁用,就看到element有个switch组件可以改造一下,就上网看了一下,结果为了这个效果忙活了很久。。。所以说记录一下,让大家少踩坑。 前置条件 先看完我的需求再…...
(二)丶RabbitMQ的六大核心
一丶什么是MQ Message Queue(消息队列)简称MQ,是一种应用程序对应用程序的消息通信机制。在MQ中,消息以队列形式存储,以便于异步传输,在MQ中,发布者(生产者)将消息放入队列ÿ…...
微信小程序实现上下手势滑动切换
效果图 思路 实现一个微信小程序的复合滚动页面,主要通过Swiper组件实现垂直方向的轮播功能,每个轮播项内部使用Scroll-View组件来展示可垂直滚动的长内容,如图片和文本。 代码 <!-- wxml --> <view class"swiper-container…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...

