当前位置: 首页 > news >正文

优选算法——双指针

前言

本篇博客为大家介绍双指针问题,它属于优选算法中的一种,也是一种很经典的算法;算法部分的学习对我们来说至关重要,它可以让我们积累解题思路,同时也可以大大提升我们的编程能力,本文主要是通过一些题目来为大家介绍,这里统一说明一下,每一道题我会粘贴原题链接,大家可以先做再来看解析,这样会更有针对性,下面进入正文。

1. 移动零

题目链接:. - 力扣(LeetCode)

题目解析:本题大家读完后应该可以很轻松地理解题目的意思,我们需要将0全部移动到数组的末尾,并且保持其他元素的顺序是不能改变的。

算法原理:这类题可以划归为数组分块问题,对于这类问题,首先想到的方法就是双指针,大家注意这里提到的指针并不是我们在C语言中学过的那个指针,这里的“指针”代表数组的下标。我们需要定义两个“指针”,一个指针用于遍历数组,另一个指针用来存储非零元素的最后一个位置,这两个“指针”会将整个数组划分为3个区间。

具体大家来看下图:

区间划分完后,我们需要让两个“指针”移动的过程中保持它们本身的性质,这样我们就可以解决这个问题,那么我们该如何保持呢?

大家可以结合题目给的例子来进行理解,上面的思路就是双指针的核心思路。

代码实现:

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

这里使用C++实现代码,一个for循环就搞定了,主要就是在于指针的调整。

2. 复写零

题目链接:. - 力扣(LeetCode)

题目解析:本题要求我们来对0进行复写,其实就是遇到0了抄两遍,不是0就抄一遍,注意题目要求就地修改,不能开辟新的数组。

算法原理:首先我们需要定义两个指针,其次需要找到最后一个复写的数,最后从后向前进行复写操作,具体大家请看下图:

这里大家要注意,我们在找最后一个复写的数的时候也同样需要用到双指针算法;其中有越界的情况,我们要进行特殊处理。

代码实现

class Solution {
public:void duplicateZeros(vector<int>& arr){//第一步:找最后一个复写的数int cur=0;int dest=-1;int n=arr.size();while(dest<n){if(arr[cur]){++dest;}else{dest+=2;}if(dest>=n-1){break;}cur++;}//第二步:处理边界if(dest==n){arr[n-1]=0;cur--;dest-=2;}//第三步:从后向前复写while(cur>=0){if(arr[cur]){arr[dest--]=arr[cur--];}else{arr[dest--]=0;arr[dest--]=0;cur--;}}}
};

这里大家看到代码,分为三部分:找最后一个复写的数、处理边界以及复写操作;还有一个小问题,有同学会想为什么必须从后往前进行复写,不能从前往后吗?

答案是不可以,大家思考一下,如果从前往后复写,那么0要写2遍,这个时候我们原始的数据就会被覆盖,这样就无法达到题目的要求。

3. 快乐数

题目链接:. - 力扣(LeetCode)

题目解析本题要求我们判断一个数是否为快乐数,那么我们首先要明确什么是快乐数;然后我们进行判断,是快乐数返回1,否则返回0。

算法原理:这道题我们也可以使用双指针来解决,具体来说就是快慢指针,大家可以先回想一下我们在链表的学习中遇到的这么一道题,题目要求我们判断环形链表,当时我们使用了快慢指针的方法来解决,那么本题我们同样可以使用这种思想来解决。根据之前的结论,大家首先需要明确,当我们不断进行题目要求的操作时,一定会进入一个循环,这里要么是1一直循环;要么是循环其他不为1的数据,所以每次计算得到的数可以串起来看成一个“链表”,这样就和我们之前说过的环形链表殊途同归了。我们只需要定义一个慢指针,一个快指针,在循环的过程中,快指针一定会追上慢指针,我们判断相遇的时候的值是不是1,即可判断给定的数是不是快乐数。

 

代码实现

class Solution 
{
public:int test(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;int fast=test(n);while(slow!=fast){slow=test(slow);fast=test(test(fast));}return slow==1;}
};

这里补充一个小问题,就是实现题目中要求的操作,每一位的平方和相加,这个想必大家在C语言阶段就已经接触过,这里大家看代码应该很容易理解。

4. 盛水最多的容器

题目链接:. - 力扣(LeetCode)

题目解析:本题要求找到盛水最多的容器,本质就是让我们找出两个数来确定一个容器,使这个容器的“容积”最大;那么本题大部分人的第一反应就是暴力枚举,把每一个乘积都求出来,然后对比找出最大的,这是一种很容易理解的思路,但是代码的时间复杂度会非常高,效率就比较低,所以不可行。

算法原理:本题我们要使用双指针来解决问题,具体是运用左右指针,一个指针从左往右,另一个指针从右往左,两个指针向中间靠拢,哪边高度小哪边就往里动,下面说明了这样做的原理,利用了单调性来找到规律。

代码实现

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

5. 有效三角形的个数

题目链接:. - 力扣(LeetCode)

题目解析:本题要求我们在一组数中选出可以构成三角型的数字组合,其实就是求有多少种选法,这里大家注意看例子的提示,重复选的数也是OK的,只要是不同位置的数就满足条件。

算法原理

本题我们不能使用暴力解法来做,那样时间复杂度太高,效率很低;那么我们进行优化,使用双指针来解决问题,具体流程大家可以看下图,首先我们先将数据进行排序,再来固定最大的数,然后定义左右两个指针,根据两种不同的情况移动指针,循环操作,就可以解决本题。

代码实现

class Solution {
public:int triangleNumber(vector<int>& nums) {//排序sort(nums.begin(),nums.end());int ret=0;int n=nums.size();for(int i=n-1;i>=2;i--)//固定最大数{int left=0;int right=i-1;while(left<right){if(nums[left]+nums[right]>nums[i]){ret+=right-left;right--;}else{left++;}}}return ret;}
};

6. 查找总价格为目标值的两个商品

题目链接:. - 力扣(LeetCode)

题目解析:本题的要求很简单,就是让我们在一组数中找到两个数,使它们的和等于目标值。

算法原理:本题其实大部分人第一时间还是会想到暴力解法,运用了两个循环,遍历所有情况,判断是否等于target,这样做很好理解,但是代码的时间复杂度会很高,会超时,所以这种暴力解法不建议。优化版的解法就是使用双指针,定义左右指针,分为三种情况来决定指针的移动,具体大家请看下图。

代码实现

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

总结

本篇博客为大家介绍了双指针算法,它可以帮助我们解决很多原本复杂的问题,大家需要掌握这种思想,当我们遇到需要将数据分区间进行处理的时候,我们可以考虑双指针,这其中还包括了快慢指针的思路,最后希望本篇博客可以为大家带来帮助,感谢阅读!

相关文章:

优选算法——双指针

前言 本篇博客为大家介绍双指针问题&#xff0c;它属于优选算法中的一种&#xff0c;也是一种很经典的算法&#xff1b;算法部分的学习对我们来说至关重要&#xff0c;它可以让我们积累解题思路&#xff0c;同时也可以大大提升我们的编程能力&#xff0c;本文主要是通过一些题…...

【Rabbitmq篇】RabbitMQ⾼级特性----消息确认

目录 前言&#xff1a; 一.消息确认机制 • ⾃动确认 • ⼿动确认 手动确认方法又分为三种&#xff1a; 二. 代码实现&#xff08;spring环境&#xff09; 配置相关信息&#xff1a; 1&#xff09;. AcknowledgeMode.NONE 2 &#xff09;AcknowledgeMode.AUTO 3&…...

开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 本文主要介绍如何在Windows系统电脑使用整合包一键部署开源TTS语音克隆神器GPT-SoVITS&#xff0c;并结合cpolar内网穿透工…...

【idea】更换快捷键

因为个人习惯问题需要把快捷键替换一下。我喜欢用CTRLD删除一下&#xff0c;用CTRLY复制一样。恰好这两个快捷键需要互换一下。 打开file——>setting——>Keymap——>Edit Actions 找到CTRLY并且把它删除 找到CTRLD 并且把它删除 鼠标右键添加CTRLY 同样操作在Delet…...

最小的子数组(leetcode 209)

给定一个正整数数组&#xff0c;找到大于等于s的连续的最小长度的区间。 解法一&#xff1a;暴力解法 两层for循环&#xff0c;一个区间终止位置&#xff0c;一个区间起始位置&#xff0c;找到大于等于s的最小区间长度&#xff08;超时了&#xff09; 解法二&#xff1a;双指…...

IDEA-Plugins无法下载插件(网络连接问题-HTTP Proxy Settings)

IDEA-Plugins无法下载插件&#xff08;网络连接问题&#xff09; 改成如下配置&#xff1a; 勾选 添这个url即可&#xff1a;https://plugins.jetbrains.com/ 重启插件中心&#xff0c;问题解决。...

AWTK-WIDGET-WEB-VIEW 发布

awtk-widget-web-view 是通过 webview 提供的接口&#xff0c;实现的 AWTK 自定义控件&#xff0c;使得 AWTK 可以方便的显示 web 页面。 项目网址&#xff1a; https://gitee.com/zlgopen/awtk-widget-web-view webview 提供了一个跨平台的 webview 接口&#xff0c;是一个非…...

Mysql每日一题(if函数)

两种写法if()和case if()函数 select *,if(T.xT.y>T.z and T.xT.z>T.y and T.yT.z>T.x,Yes,No) as triangle from Triangle as T; case方法 select *, case when T.xT.y>T.z and T.xT.z>T.y and T.yT.z>T.x then Yes else No end as triangle from Trian…...

Spring Cloud Alibaba [Gateway]网关。

1 简介 网关作为流量的入口&#xff0c;常用功能包括路由转发、权限校验、限流控制等。而springcloudgateway 作为SpringCloud 官方推出的第二代网关框架&#xff0c;取代了Zuul网关。 1.1 SpringCloudGateway特点: &#xff08;1&#xff09;基于Spring5&#xff0c;支持响应…...

【动手学深度学习Pytorch】2. Softmax回归代码

零实现 导入所需要的包&#xff1a; import torch from IPython import display from d2l import torch as d2l定义数据集参数、模型参数&#xff1a; batch_size 256 # 每次随机读取256张图片 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size) # 将展平每个…...

技术周总结 11.11~11.17 周日(Js JVM XML)

文章目录 一、11.11 周一1.1&#xff09;问题01&#xff1a;js中的prompt弹窗区分出来用户点击的是 确认还是取消进一步示例 1.2&#xff09;问题02&#xff1a;在 prompt弹窗弹出时默认给弹窗中写入一些内容 二、11.12 周二2.1) 问题02: 详解JVM中的本地方法栈本地方法栈的主要…...

MATLAB 使用教程 —— 矩阵和数组

矩阵和数组MATLAB 中矩阵和数组长什么样&#xff1f;MATLAB 怎么用矩阵计算&#xff1f;创建和操作矩阵矩阵运算示例串联 访问矩阵的元素 矩阵和数组 MATLAB 是“matrix laboratory”的缩写形式。MATLAB 主要用于处理 整个的矩阵和数组&#xff0c;而其他编程语言大多逐个处理…...

React教程第二节之虚拟DOM与Diffing算法理解

1、什么是虚拟DOM 虚拟DOM 是javascript的一个对象&#xff0c;是内存中的一种数据结构&#xff0c;以树的形式存储UI的状态&#xff0c;树中的每个节点都代表着真实的DOM&#xff0c;用来描述我们希望在页面看到的 HTML结构&#xff1b; 现在的MVVM 框架&#xff0c;大多使用…...

C++——类和对象(part2)

前言 本篇博客继续为大家介绍类与对象的知识&#xff0c;承接part1的内容&#xff0c;本篇内容是类与对象的核心内容&#xff0c;稍微有些复杂&#xff0c;如果你对其感兴趣&#xff0c;请继续阅读&#xff0c;下面进入正文部分。 1. 类的默认成员函数 默认成员函数就是用户…...

【FFmpeg系列】:音频处理

前言 在多媒体处理领域&#xff0c;FFmpeg无疑是一个不可或缺的利器。它功能强大且高度灵活&#xff0c;能够轻松应对各种音频和视频处理任务&#xff0c;无论是简单的格式转换&#xff0c;还是复杂的音频编辑&#xff0c;都不在话下。然而&#xff0c;要想真正发挥FFmpeg的潜…...

Python绘制雪花

文章目录 系列目录写在前面技术需求完整代码代码分析1. 代码初始化部分分析2. 雪花绘制核心逻辑分析3. 窗口保持部分分析4. 美学与几何特点总结 写在后面 系列目录 序号直达链接爱心系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4…...

vue3 如何调用第三方npm包内部的 pinia 状态管理库方法

抛砖引玉: 如果在开发vue3项目是, 引用了npm第三方包 ,而且这个包内使用了Pinia 状态管理库,那我们如何去调用 npm内部的 Pinia 状态管理库呢? 实际遇到的问题: 今天在制作npm包时遇到的问题,之前Vue2版本的时候状态管理库用的Vuex ,当时调用npm包内的状态管理库很简单,直接引…...

uni-app快速入门(七)--组件路由跳转和API路由跳转及参数传递

uni-app有两种页面路由跳转模式&#xff0c;即使用navigator组件跳转和调用API跳转&#xff0c;API调转不要理解为调用后台接口的API&#xff0c;而是指脚本函数中使用跳转函数。 一、组件路由跳转 1.1 打开新页面 打开新页面使用组件的open-type"navigate",见下面…...

Flink升级程序和版本

Flink DataStream程序通常设计为长时间运行,如几周、几个月甚至几年。与所有长时间运行的服务一样,Flink streaming应用程序也需要维护,包括修复错误、实现改进或将应用程序迁移到更高版本的Flink集群。 这里就来描述下如何更新Flink streaming应用程序,以及如何将正在运行…...

从0安装mysql server

安装 MySQL Server 首先,你需要在 Ubuntu 上安装 MySQL 服务器。运行以下命令来安装:sudo apt update sudo apt install mysql-server安装完成后,MySQL 服务会自动启动。你可以通过以下命令检查 MySQL 服务是否正在运行: sudo systemctl status mysql如果 MySQL 正在运行,…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...