算法思想总结:双指针算法

一、移动零

. - 力扣(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题)
        注意事项:对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环)

        如果后面还有关双指针的经典题目,博主会继续在这篇更新的!!

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

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

相关文章

【Linux】Shell编程【二】

目录 Shell流程控制条件测试注意事项示例[ condition ]与[[ condition ]]的区别 if条件单分支语法示例1&#xff1a;统计根分区使用率示例2&#xff1a;创建目录 双分支if条件语句语法案例1&#xff1a;备份mysql数据库案例2&#xff1a;判断apache是否启动&#xff0c;如果没有…

网络学习:9个计算机的“网络层”知识点

目录 一、IP 地址 1.1 分类表示法&#xff1a; 1.1.1 分类表示地址的其他说明 1.2 无分类编址 CIDR 二、IP 数据报文格式 Q: IP 报文里有什么&#xff1f;可以不按顺序或者字节来讲一讲 三、 路由概念 3.1 路由表 3.2 路由网络匹配 3.3 ARP 解析 3.4 RARP 逆地址解析…

考试题库:华为HCIA-Datacom易错题⑦(含答案解析)

华为认证HCIA-Datacom易错题举例和答案分析。 1、现有一台交换机通过某端口与一个指定端口相连&#xff0c;但是该端口不转发任何报文&#xff0c;却可以通过接收BPDU来监听网络变化&#xff0c;那么该端口的角色应该是&#xff08; &#xff09;。 A、Designated端口 B、Al…

分布式搜索elasticsearch(1)

1.初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海量数据中快速找到需要的内容 例如&#xff1a; 在GitHub搜索代码 在电商网站搜索商品 在百度搜索答案…

c++函数SetConsoleTextAttribute

前言 正文 1.作用&#xff1a; 2.函数格式(重点)&#xff1a; 3.参数(重点)&#xff1a; 前言 实用(真的) 正文 1.作用&#xff1a; 更改cmd的背景色与字体颜色 2.函数格式(重点)&#xff1a; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),10进制参数); …

第14届环境与农业工程国际会议(ICEAE 2024)即将召开!

2024年第14届环境与农业工程国际会议&#xff08;ICEAE 2024&#xff09;将于6月7日至9日在泰国曼谷召开。本次会议旨在促进环境与农业工程的研究和开发活动&#xff0c;共同探讨领域内最新以及具有根本性的进展突破。热忱欢迎从事相关领域研究的专家&#xff0c;学者和专业技术…

iStoreOS系统内安装HomeAssistant服务

iStoreOS系统内安装HomeAssistant服务 1. HomeAssistant服务 HomeAssistant是一款基于Python的开源智能家居系统&#xff0c;简称HA。 HomeAssistant可以方便地连接各种外部设备&#xff0c;如智能设备、摄像头、邮件、短消息和云服务等&#xff0c;其成熟的可连接组件有近千…

【Twinmotion】Twinmotion导入UE5

步骤 1. 在虚幻商城中安装“Datasmith Twinmotion导入器插件” 安装“面向虚幻引擎的Twinmotion内容” 2. 打开虚幻引擎&#xff0c;在插件中搜索“twinmotion”&#xff0c;勾选如下两个插件&#xff0c;然后重启虚幻引擎 3. 打开Twinmotion&#xff0c;随便添加一个物体 导出…

【阿里云系列】-ACK的Java应用POD无法访问云数据库Redis

问题介绍 如下图所示&#xff0c;是ACK集群的POD访问阿里云的云数据库Redis&#xff0c;如何实现访问呢 配置步骤 要实现ACK集群内的所有POD都可以访问云数据库Redis&#xff0c;则需要在Redsi的白名单里增加源IP或网段&#xff0c;如下图所示 注意&#xff1a; 以上添加…

网络套接字-UDP服务器

一 预备知识 1 端口号和进程id 主机间的数据传输本质是两个进程在通信&#xff0c;就像是我们打开抖音刷视频&#xff0c;视频不是都保存在手机上的&#xff0c;而是服务器发送给你的&#xff0c;这里就是用到了网络。 那如何保证把数据给指定进程呢? 就是用端口号去标识主机中…

Pytorch学习 day13(完整的模型训练步骤)

步骤一&#xff1a;定义神经网络结构 注意&#xff1a;由于一次batch_size的大小为64&#xff0c;表示一次放入64张图片&#xff0c;且Flatten()只会对单张图片的全部通道做拉直操作&#xff0c;也就是不会将batch_size合并&#xff0c;但是一张图片有3个通道&#xff0c;在Ma…

YOLOv9改进项目|关于本周更新计划的说明24/3/12

目前售价售价59.9&#xff0c;改进点30个 专栏地址&#xff1a; 专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 日期&#xff1a;24/3/12 本周更新计划说明&#xff1a; 1. 更新华为Gold YOLO中的…

读西游记第一回:西游记世界格局

天地之数&#xff1a; 元&#xff1a;十二万九千六百岁&#xff08;129600年&#xff09; 1元12会&#xff1a;子、丑、寅、卯、巳、午、未、申、酉、戌、亥。每会18000年。与12地支对应。 亥会期&#xff1a;前5400年混沌期&#xff0c;后5400年&#xff0c;盘古开天辟地&am…

论文阅读——Vision Transformer with Deformable Attention

Vision Transformer with Deformable Attention 多头自注意力公式化为&#xff1a; 第l层transformer模块公式化为&#xff1a; 在Transformer模型中简单地实现DCN是一个non-trivial的问题。在DCN中&#xff0c;特征图上的每个元素都单独学习其偏移&#xff0c;其中HWC特征图上…

Mysql数据库学习笔记——第二篇

DML 添加数据 INSERT INTO 表名(字段1,字段2,……) VALUES(值1,值2,……); # 给指定字段添加数据INSERT INTO 表名 VALUES(值1,值2,……); # 给全部字段添加数据INSERT INTO 表名(字段1,字段2,……) VALUES(值1,值2,……),(值1,值2,……),(值1,值2,……); …

【开发】微服务整合Sentinel

目录 前言 1W&#xff1a;什么是Sentinel&#xff1f; 2W&#xff1a;为什么使用Sentinel&#xff1f; 3W&#xff1a;如何使用Sentinel&#xff1f; 1. 在pom.xml中导入Sentinel依赖坐标 2. 配置控制台 3. 访问API接口的任意端点 流量控制 1. 簇点链路 2. 快速入门…

某医院系统未授权访问

开局还是先测一下登录框&#xff0c;弱密码走一波&#xff0c;无果 通过指纹识别出该站是springboot开发&#xff0c;扫描目录查看是否存在泄露 存在泄露&#xff0c;访问地址 很多接口&#xff0c;不可能一个一个手动测试吧&#xff0c;上工具 工具扫描完会生成文档&#xff0…

算法(结合算法图解)

算法简介简单查找二分查找法 选择排序内存的工作原理数组和链表数组选择排序小结 递归小梗 要想学会递归&#xff0c;首先要学会递归。 递归的基线条件和递归条件递归和栈小结 快速排序分而治之快速排序合并排序时间复杂度的平均情况和最糟情况小结 散列表散列函数缓冲小结性能…

Ubuntu系统下查看安装的CUDA和CUDNN的版本

一、查看 CUDA 版本&#xff1a; #查看cuda版本和显存使用情况nvidia-smi 二、查看 CUDNN 版本&#xff1a; 安装链接&#xff1a;cuDNN Archive | NVIDIA Developer #回到系统主目录 cd ~ #查看cudnn版本 cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJO…

华为机考:HJ43 迷宫问题

华为机考&#xff1a;HJ43 迷宫问题 描述 DFS 从迷宫入口开始进行dfs搜索&#xff0c;每次进入一个点&#xff0c;将其加入临时路径数组中&#xff0c;把该位改成0表示不能进入&#xff0c;然后依次搜索该位下、右、上、左四个方向的点&#xff0c;如果搜索的这个点可以进入则…