双指针算法总结

双指针算法大致有以下几个类型

  • 对撞指针:一般用来处理两数和问题
  • 快慢指针: 一般在链表中用的比较多,如求链表中间结点,链表是否有环等,当然一些非链表题也会用到相关的思想
  • 区间划分: 将数组分成两个不同性质的两个部分

 一、对撞指针

1.盛⽔最多的容器(点击这里,直达题目)

 看到这题,最直接的想法就是暴力,两层for循环直接枚举左右端点,在所有的情况中找到最大值,时间复杂度是O(n^2),过不了,那么我们怎么优化时间复杂度?

这两个问题就是双指针思路的关键,这里就解释一下为什么是方案1,因为S=h * w,而此时的w只能减小,那么我们如果想让S变大,就只能将h变大,而h是由两边较低的高度决定的,如果我们移动较高的那条边,那么h就会受限于较低的那条边的高度,所以S只会变小,这就导致我们只能移动较低的那条边,而这也就能保证这个算法的正确性,即我们是将没有枚举到的情况排除了,并不是说枚举漏了,代码如下

class Solution {
public:int maxArea(vector<int>& height) {int left=0,right=height.size()-1,ans=0;while(left<right){ans=max(ans,min(height[left],height[right])*(right-left));if(height[left]<height[right])left++;elseright--;}return ans;}
};

2.和为s的两个数字(点击这里,直达题目)

 

 这题当然也是可以直接暴力枚举,两层for循环结束,时间复杂度是O(n^2),但是题目中给的排序条件我们没有用上,那么我们如何利用这个条件优化时间复杂度?

选方案2,理由如下

因为s=17,而target=9,所以我们需要让s变小,而中间的元素都比nums[left]大,比nums[right]小,如果移动left,只能让s更大,所以我们移动right,让s减小,如果遇到s<target的情况,就移动left,理由同上,而我们能这么做的根本原因在于数组有序,(思路的正确性的分析同上一题)

代码如下

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {int left=0,right=nums.size()-1;while(left<right){int sum=nums[left]+nums[right];if(sum==target) return {nums[left],nums[right]};if(sum<target) left++;else right--;}return {};}
};

当然我们还能求s<target的数字对个数,s>target的数字对个数等等,同样的分析方法,就留给大家做练习了。

总结一下:能否使用对撞指针,主要看是否满足"单调性",即在固定其中一个指针的情况下,left和right从逻辑上来说只能有一个发生移动,当我们不确定时,就照着上面的分析方法试试看

二、快慢指针

这个一般在链表中用的比较多,很多链表的经典题目都会用到,这里就不细讲在链表中的应用了,一般链表的题目大家都很容易想到这个思想,但是一旦题目脱离了链表,我们基本就不会有意识的想到这种思想,如下面这道题

快乐数(点击这里,直达题目)

 这道题的关键就在于无限循环因为如果你对链表很熟悉的话,你就会想到链表有环的相关问题,然后你就会想到快慢指针,而这就是这道题的解法

好,我们来看一下这道题,就是判断数是否是快乐数,如果是,那么在经过一段重复的操作之后,会变为1,如果不是,则会一直循环,本质不是和判断链表是否有环一摸一样的问题吗?没环,则链表会走到NULL,有环,则一直循环。至于有人说的无限循环,也可能是走一直不重复的数字,这个问题后面会简单证明一下,这里就先默认要么为1,要么循环

代码如下

class Solution {
public:int Get(int x){int res=0;while(x){res+=(x%10)*(x%10);x/=10;}return res;}bool isHappy(int n) {int fast=Get(n),slow=n;while(fast!=slow)//如果相等停下来,1也可以看成循环,只是循环的数字一直是1{slow=Get(slow);//相当于链表中slow往后走一步fast=Get(Get(fast));//相当于链表中fast往后走两步}return slow==1;//判断是否是快乐数}
};

 总结一下:快慢指针的思想不是只能出现在链表中,我们要能通过题目给的信息找出它和链表题之间的关系,实现知识的迁移变形

三、区间划分

移动零(点击这里,直达题目)

 我们的思路是根据题目要求维护三个区间,被双指针分割出来的三个区间

 

 代码如下

class Solution {
public:void moveZeroes(vector<int>& nums) {for(int i=0,j=0;j<nums.size();j++)if(nums[j])swap(nums[i++],nums[j]);}
};

这题的思路其实和快排中,选定目标值target,然后将数组分为<=target和>target两部分的实现一样,都是划分数组,维护区间,忘记的可以去回顾一下

总结一下:当遇到要将数组划分区间的题目时,可以想想能不能用双指针来做

当然这题用快慢指针的思想也能做,代码如下

class Solution {
public:void moveZeroes(vector<int>& nums) {int j=0;for(int i=0;i<nums.size();i++)if(nums[i])nums[j++]=nums[i];while(j<nums.size())nums[j++]=0;}
};

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

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

相关文章

next.js报错点

next.js报错点 1.类型“{ children: ReactNode; }”与类型“IntrinsicAttributes”不具有相同的属性。2. 不能将类型“void[]”分配给类型“ReactNode”&#xff1f;3.useRouter only works in Client Components. Add the "use client" directive at the top of the…

【LeetCode 】数组简介

集合列表和数组 本文中介绍的概念为适用于所有编程语言的抽象理论&#xff0c;具体实现会由编程语言的不同而稍有差别。 具体介绍数组之前&#xff0c;我们先来了解一下集合、列表和数组的概念之间的差别。 集合 集合一般被定义为&#xff1a;由一个或多个确定的元素所构成的…

Python读取Excel:实现数据高效处理的利器

目录 一、Python读取Excel的常用库二、Python读取Excel的步骤三、具体案例和使用场景四、Python读取Excel的优势与其他编程语言比较 摘要 本文将介绍Python读取Excel的方法&#xff0c;并通过具体案例和使用场景展示如何实现数据高效处理。我们将介绍常用的Python库&#xff0c…

[docker][WARNING]: Empty continuation line found in:

报警内容&#xff1a; 下面展示一些 内联代码片。 //执行 sudo docker build ubuntu:v1.00 . [WARNING]: Empty continuation line found in:出现上述错误原因为18行多了一个 " \" 符号&#xff0c;去除即可

卷积神经网络实现天气图像分类 - P3

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;Pytorch实战 | 第P3周&#xff1a;彩色图片识别&#xff1a;天气识别&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff…

【LeetCode75】第三十五题 统计二叉树中好节点的数目

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 给我们一棵二叉树&#xff0c;让我们统计这棵二叉树中好节点的数目。 那么什么是好节点&#xff0c;题目中给出定义&#xff0c;从根节点…

1782. 统计点对的数目

给你一个无向图&#xff0c;无向图由整数 n &#xff0c;表示图中节点的数目&#xff0c;和 edges 组成&#xff0c;其中 edges[i] [ui, vi] 表示 ui 和 vi 之间有一条无向边。同时给你一个代表查询的整数数组 queries 。 第 j 个查询的答案是满足如下条件的点对 (a, b) 的数…

实现高效消息传递:使用RabbitMQ构建可复用的企业级消息系统

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

【Linux】动态库和静态库

动态库和静态库 软链接硬链接硬链接要注意 自定义实现一个静态库(.a)解决、使用方法静态库的内部加载过程 自定义实现一个动态库&#xff08;.so&#xff09;动态库加载过程 静态库和动态库的特点 软链接 命令:ln -s 源文件名 目标文件名 软链接是独立连接文件的&#xff0c;他…

Tomcat运行后localhost:8080访问自己编写的网页

主要是注意项目结构&#xff0c;home.html放在src/resources/templates下的home.html下&#xff0c;application.properties可以不做任何配置。还有就是关于web包的位置&#xff0c;作者一开始将web包与tabtab包平行&#xff0c;访问8080出现了此类报错&#xff1a; Whitelabel…

c++ qt--页面布局(第五部分)

c qt–页面布局&#xff08;第五部分&#xff09; 一.页面布局 在设计页面的左侧一栏的组件中我们可以看到进行页面布局的一些组件 布局组件的使用 1.水平布局 使用&#xff1a;将别的组件拖到水平布局的组件中即可&#xff0c;可以选择是在哪个位置 2.垂直布局 使用&…

【业务功能篇81】微服务SpringCloud-ElasticSearch-Kibanan-docke安装-入门实战

ElasticSearch 一、ElasticSearch概述 1.ElasticSearch介绍 ES 是一个开源的高扩展的分布式全文搜索引擎&#xff0c;是整个Elastic Stack技术栈的核心。它可以近乎实时的存储&#xff0c;检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;…

GB28181设备接入侧如何对接外部编码后音视频数据并实现预览播放

技术背景 我们在对接GB28181设备接入模块的时候&#xff0c;遇到这样的技术诉求&#xff0c;好多开发者期望能提供编码后&#xff08;H.264/H.265、AAC/PCMA&#xff09;数据对接&#xff0c;确保外部采集设备&#xff0c;比如无人机类似回调过来的数据&#xff0c;直接通过模…

Vue中使用element-plus中的el-dialog定义弹窗-内部样式修改-v-model实现-demo

效果图 实现代码 <template><el-dialog class"no-code-dialog" v-model"isShow" title"没有收到验证码&#xff1f;"><div class"nocode-body"><div class"tips">请尝试一下操作</div><d…

C语言易错点整理

前言&#xff1a; 本文涵盖了博主在平常写C语言题目时经常犯的一些错误&#xff0c;在这里帮大家整理出来&#xff0c;一些易错点会帮大家标识出来&#xff0c;希望大家看完这篇文章后有所得&#xff0c;引以为戒~ 一、 题目&#xff1a; 解答&#xff1a; 首先在这个程序中…

Unity ProBuilder SetUVs 不起作用

ProBuilder SetUVs 不起作用 &#x1f41f; 需要设置face.manulUV true public static void Set01UV(this ProBuilderMesh mesh){foreach (var face in mesh.faces){face.manualUV true;//设置为手动uv}var vertices mesh.GetVertices().Select(v > v.position).ToArray(…

mq与mqtt的关系

文章目录 mqtt 与 mq的区别mqtt 与 mq的详细区别传统消息队列RocketMQ和微消息队列MQTT对比&#xff1a;MQ与RPC的区别 mqtt 与 mq的区别 mqtt&#xff1a;一种通信协议&#xff0c;规范 MQ&#xff1a;一种通信通道&#xff08;方式&#xff09;&#xff0c;也叫消息队列 MQ…

openCV实战-系列教程5:边缘检测(Canny边缘检测/高斯滤波器/Sobel算子/非极大值抑制/线性插值法/梯度方向/双阈值检测 )、原理解析、源码解读

打印一个图片可以做出一个函数&#xff1a; def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows() 1、Canny边缘检测流程 Canny是一个科学家在1986年写了一篇论文&#xff0c;所以用自己的名字来命名这个检测算法&#xff0c;Canny边缘检测算法…

C#-Tolewer和ToUpper的使用

目录 简介: 好处:​ 过程: 总结&#xff1a; 简介: 字符串是不可变的&#xff0c;所以这些函数都不会直接改变字符串的内容&#xff0c;而是把修改后的字符串的值通过函数返回值的形式返回。 ToLower和ToUpper是字符串处理函数&#xff0c;用于将字符中的英文字母转换为小…

使用DPO微调Llama2

简介 基于人类反馈的强化学习 (Reinforcement Learning from Human Feedback&#xff0c;RLHF) 事实上已成为 GPT-4 或 Claude 等 LLM 训练的最后一步&#xff0c;它可以确保语言模型的输出符合人类在闲聊或安全性等方面的期望。然而&#xff0c;它也给 NLP 引入了一些 RL 相关…