【算法】双指针算法

个人主页 : zxctscl
如有转载请先通知

题目

  • 1. 283. 移动零
    • 1.1 分析
    • 1.2 代码
  • 2. 1089. 复写零
    • 2.1 分析
    • 2.2 代码
  • 3. 202. 快乐数
    • 3.1 分析
    • 3.2 代码
  • 4. 11. 盛最多水的容器
    • 4.1 分析
    • 4.2 代码
  • 5. LCR 179. 查找总价格为目标值的两个商品
    • 5.1 分析
    • 5.2 代码
  • 6. 15. 三数之和
    • 6.1 分析
    • 6.2 代码

1. 283. 移动零

在这里插入图片描述

1.1 分析

一、题目分析
要将0放在所有数组的最后,而且非零元素的顺序保持不变,要求原地对数组进行移动。

二、算法原理
用两个指针来讲数组进行划分,一个cur:从左往右扫描数组,遍历数组;一个dest:已经处理的区间内,非零元素的最后一个位置。
就将数组分为3个区间:非零:[0,dest];0区间:[dest+1,cur-1];待处理的区间:[cur,n-1].
要想这样划分,cur就得从前往后在遍历的过程中,遇到0元素,就加加;遇到非零元素,就将dest+1位置和cur位置的值交换。
在这里插入图片描述

在这里插入图片描述

1.2 代码

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

2. 1089. 复写零

在这里插入图片描述

2.1 分析

一、题目解析
要求每次遇到0就复写,而且不能改变原数组的长度。

二、算法原理
如果用双指针从前往后遍历,就拿例1来说,
就会出现值被覆盖的情况:
在这里插入图片描述
所以遍历顺序就不能从前往后。
那么就把顺序改为从后往前遍历,但是不能超过原数组的长度,就得先找一下cur和dest开始的位置。
可以先用双指针算法:1.先判断cur位置;2.决定dest向后移动一步或者两步;3.判断一下dest是否已经到达结束位置;4.在把cur加加。
但是可能会出现dest越界的情况,如果n-1位置为0,那么cur就减减,dest就减2。
最后在从后往前开始复写0。

在这里插入图片描述

2.2 代码

class Solution {
public:void duplicateZeros(vector<int>& arr) {int cur=0,dest=-1;int n=arr.size();while(cur<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--;}}}
};

3. 202. 快乐数

在这里插入图片描述

3.1 分析

一、题目分析
题目中所说最后的平方和为1才是快乐数,如果不为1,就一直循环,其实可以看成两个都是循环,一个一直循环的是1,另一个循环的值都不相同。只需要判断循环里面的值是不是为1就可以。

二、算法原理
先用一个变量sum记录最后平方和,然后把最后一位平方,然后删掉原来的数,一直重复这个过程,直到最后一位为0,最后返回这个平方和sum。

定义两个快慢指针,用平方和来充当指针,slow指向第一个数,fast指向第二个数,如果这两个指针一直不相等,就一直循环,slow走一步,fast走两步。直到两个相遇为止,等于1就是快乐数,不等于就不是。
在这里插入图片描述

3.2 代码

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(slow!=fast){slow=bitsum(slow);fast=bitsum(bitsum(fast));}return slow==1;}
};

4. 11. 盛最多水的容器

在这里插入图片描述

4.1 分析

一、题目分析
题目中的数组代表每一条线的高度,来求最大的容积,来看一下例1:
在这里插入图片描述
选择的高度是8和7,但是题目要求不能倾斜,这里选择高度的就是7,宽度就是下标之间的差值8-1也就是7,那么容积最大就是7*7=49。

二、算法原理
用两个指针来记录容器两边的高度,可以直接先选择最大的宽度,记录下这个容积。
如果左边指针走一步,宽度在减小,高度可能会出现比之前的小,那么体积就比原来的小;高度如果不变,那么宽度减小,那么总容积也是在减小的。所以得干掉高度小的那一个值。
如果两个指针指向的值相等,那么干掉谁都可以,然后继续枚举里面相乘的容积,直到两个指针相遇,最后返回容积最大的值就行。
在这里插入图片描述

4.2 代码

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

5. LCR 179. 查找总价格为目标值的两个商品

在这里插入图片描述

5.1 分析

一、题目分析
只需要找到两个数,他们的和等于目标值就可以,但是题目中的数组是按照升序排列的,暴力解法会超时,就不考虑了。

二、算法原理
利用数组是有序的,用双指针算法来算。
定义两个指针,一个在左边,一个在右边。
先计算两个指针指向值的和,判断一下和目标值的大小,会出现三种情况:1.小于目标值,那么左边指针就加加;2.等于就返回这两个值;3.大于目标值,那么右边指针就减减。
在这里插入图片描述

5.2 代码

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

6. 15. 三数之和

在这里插入图片描述

6.1 分析

一、题目分析
题目要求返回三元数组和为1的三个不同的数,而且要求去重,来看一下例1:
它里面有[-1,0,1]、[0,1,-1]、[-1,2,-1],但是第一组和第二组的元素是相同的,就只能返回一个。
在这里插入图片描述
为了避免去重,可以先给数组排个序。

二、算法原理
排序之后,数据是有序的,这里就用双指针算法。
这里是三个数的和,可以先固定一个数a,仅想要保证这个a是小于0就行(在后面等于0相加的值不可能等于0),然后在该数后面的区间内,利用双指针算法,快速找到两个数的和,者两个数的和是a的相反数,这样这三个数相加的时候,值就为0。
这里还有可能不止一种情况,所以不要漏掉,在找到一种情况时候,左边指针和右边指针继续缩小区间找,直到两个指针相同。
那么怎么去重,已经是有序的数组,那么连续相同值的情况就不考虑了,就是在左边指针和右边指针已经找到值,就跳过重复的值。当使用完重复的元素时候,固定值也得跳过重复值。还得避免越界的情况。
在这里插入图片描述

6.2 代码

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(),nums.end());vector<vector<int>> ret;int n=nums.size();for(int i=0;i<n;){if(nums[i]>0)break;int left=i+1,right=n-1,target=-nums[i];while(left<right){int sum=nums[left]+nums[right];if(sum<target) left++;else if(sum>target)right--;else{ret.push_back({nums[i],nums[left],nums[right]});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;}
};

有问题请指出,大家一起进步!!!

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

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

相关文章

MySQL 优化总结

目标知识 MySQL执行流程图 MySQL 优化成本路线图 优化成本&#xff1a;硬件>系统配置>数据库表结构>SQL及索引。优化效果&#xff1a;硬件<系统配置<数据库表结构<SQL及索引。 MySQL 五大优化原则 减少数据返回&#xff1a;设置合理字段数据类型、启用压缩…

C++——list类及其模拟实现

前言&#xff1a;这篇文章我们继续进行C容器类的分享——list&#xff0c;也就是数据结构中的链表&#xff0c;而且是带头双向循环链表。 一.基本框架 namespace Mylist {template<class T>//定义节点struct ListNode{ListNode<T>* _next;ListNode<T>* _pre…

京东云16核64G云服务器租用优惠价格500元1个月、5168元一年,35M带宽

京东云16核64G云服务器租用优惠价格500元1个月、5168元一年&#xff0c;35M带宽&#xff0c;配置为&#xff1a;16C64G-450G SSD系统盘-35M带宽-8000G月流量 华北-北京&#xff0c;京东云活动页面 yunfuwuqiba.com/go/jd 活动链接打开如下图&#xff1a; 京东云16核64G云服务器…

算法四十天-删除排序链表中的重复元素

删除排序链表中的重复元素 题目要求 解题思路 一次遍历 由于给定的链表是排好序的&#xff0c;因此重复的元素在链表中的出现的位置是连续的&#xff0c;因此我们只需要对链表进行一次遍历&#xff0c;就可以删除重复的元素。 具体地&#xff0c;我们从指针cur指向链表的头节…

Netty学习 应用Demo之“自动回复”聊天业务

Netty实现自动回复步骤 主要分成五步 1、创建EventLoopGroup实现循环组 管理EventLoop线程 2、创建Bootstrap &#xff0c;Bootstrap对于服务端而言&#xff0c;先后设置其中的线程组group、通道channel、处理器handler、客户端通道对应的处理器childHandler 3、自定义服务器接…

C#操作MySQL从入门到精通(6)——对查询数据进行排序

前言 在和MySql数据库交互的过程中,查询数据是使用最频繁的操作,并且我们经常需要对查询到的数据进行排序后输出,比如我想查询1列数据的最小值,那么我可以将查询到的数据进行升序(从小到大)排列,然后取第一个数据就是最小值。本文详细介绍了对查询数据进行排序的各种操…

HarmonyOS4-Stage模型

Stage模型介绍【舞台模型】&#xff1a; Stage模型 应用配置文件 全局应用配置文件&#xff1a; 模块配置文件&#xff1a; Ability生命周期 页面及组件的生命周期&#xff1a; 启动模式&#xff1a; "launchType": "multiton" // 会重新建&#xff0c…

本地项目提交 Github

工具 GitIdeaGithub 账号 步骤 使用注册好的 Github 账号&#xff0c;登陆 Github&#xff1b; 创建 Repositories (存储库)&#xff0c;注意填写图上的红框标注&#xff1b; 创建完成之后&#xff0c;找到存储库的 ssh 地址或 https 地址&#xff0c;这取决于你自己的配置…

matlab:有限差分求解纳维尔(Navier)边界的双调和(Biharmonic)方程,边值为零

我们考虑如下形式的双调和方程的数值解 其中&#xff0c;Ω是欧氏空间中的多边形或多面体域&#xff0c;在其中&#xff0c;d为维度&#xff0c;具有分段利普希茨边界&#xff0c;满足内部锥条件&#xff0c;f(x) ∈ L2(Ω)是给定的函数&#xff0c;∆是标准的拉普拉斯算子。算…

javaScript手写专题——实现instanceof/call/apply/bind/new的过程/继承方式

目录 原型链相关 手写instanceof 实现一个_instance方法&#xff0c;判断对象obj是否是target的实例 测试 手写new的过程 实现一个myNew方法&#xff0c;接收一个构造函数以及构造函数的参数&#xff0c;返回构造函数创建的实例对象 测试myNew方法 手写类的继承 ES6&…

【单片机】PMS5003,PM2.5传感器数据读取处理

文章目录 传感器介绍数据处理解析pm2.5的代码帮助、问询 传感器介绍 PMS5003是一款基于激光散射原理的数字式通用颗粒物浓度传感器,可连续采集 并计算单位体积内空气中不同粒径的悬浮颗粒物个数,即颗粒物浓度分布,进而 换算成为质量浓度,并以通用数字接口形式输出。本传感器可…

3D Web轻量化引擎HOOPS Commuicator如何从整体装配中创建破碎的装配零件和XML?

前言 虽然可以从某些本机CAD格式&#xff08;其子组件驻留在单独的文件中&#xff0c;例如CATIA V5、Creo - Pro/E、NX或SolidWorks&#xff09;创建破碎装配&#xff0c;但无法从整体装配文件&#xff08;例如IFC、Revit&#xff09;创建或3DXML。 本文介绍了一个示例&#…

12.C++常用的算法_遍历算法

文章目录 遍历算法1. for_each()代码工程运行结果 2. transform()代码工程运行结果 3. find()代码工程运行结果 遍历算法 1. for_each() 有两种方式&#xff1a; 1.普通函数 2.仿函数 代码工程 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vect…

基于拉格朗日分布算法的电动汽车充放电调度MATLAB程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 程序简介 该模型主要做的是基于拉格朗日分布算法的电动汽车充放电调度模型。利用蒙特卡洛模拟法模拟出电动汽车负荷曲线&#xff0c;并求解出无序充电功率曲线和有序充电曲线&#xff0c;该模型在电动汽车个…

【Linux 学习】进程优先级和命令行参数!

1. 什么是优先级? 指定进程获取某种资源&#xff08;CPU&#xff09;的先后顺序&#xff1b; Linux 中优先级数字越小&#xff0c;优先级越高&#xff1b; 1.1 优先级和权限的区别&#xff1f; 权限 &#xff1a; 能不能做 优先级&#xff1a; 已经能了&#xff0c;但是获…

RX8111CE支持电池供电设备实现多计算芯片的数据交互

随着电池技术的发展&#xff0c;其容量和质量得到了显著提高。在目前的电池供电设备中&#xff0c;常常也会将传统主处理器和协处理器的结构应用到其中&#xff0c;这种计算机结构的引入大幅度提高了电池供电设备的计算能力&#xff0c;但是对设计也提出了更高的要求。在时钟系…

【Linux】虚拟化技术docker搭建SuitoCRM系统及汉化

CRM系统 CRM&#xff08;Customer Relationship Management&#xff0c;客户关系管理&#xff09;系统是一种用于管理和优化企业与客户关系的软件工具。在商业竞争激烈的现代社会中&#xff0c;CRM系统已成为许多企业提高销售、增强客户满意度和实现持续增长的重要工具。 搭建…

FMEA风险分析中几个常用的模型——SunFMEA软件

FMEA风险分析是确保风险管理成效的重要环节之一。为了很好地实施风险分析&#xff0c;风险管理专家开发了许多模型帮助其顺利实施&#xff0c;这些模型包括&#xff1a;领结模型、风险指数模型、因果模型、安全栅分析模型等。今天SunFMEA软件系统和大家一起分享这几种常用得模型…

libVLC 提取视频帧使用QGraphicsView渲染

在前面章节中&#xff0c;我们讲解了如何使用QWidget渲染每一帧视频数据&#xff0c;这种方法对 CPU 负荷较高。 libVLC 提取视频帧使用QWidget渲染-CSDN博客 后面又讲解了使用OpenGL渲染每一帧视频数据&#xff0c;使用 OpenGL去绘制&#xff0c;利用 GPU 减轻 CPU 计算负荷…

【前端捉鬼记】使用nvm切换node版本后再用node -v查看仍然是原来的版本

今天遇到一个诡异的问题&#xff0c;使用nvm切换node版本&#xff0c;明明提示已经切换成功&#xff0c;可是再次查看node版本还是之前的&#xff01; 尝试了很多办法&#xff0c;比如重新打开一个cmd窗口、切换前执行nvm install version都没成功&#xff0c;直到找到这篇文章…