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

算法---双指针一

算法原理

双指针

常见的双指针有两种形式,一种是对撞指针,一种是左右指针

对撞指针:一般用于顺序结构中,也称左右指针,对撞指针一般从两端向中间移动,终止条件一般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环)

快慢指针:又叫龟兔赛跑算法,基本思想就是使用两个移动速度不同的指针在数组或链表等结构上移动(我们在数据结构学习链表解决链表有环问题的时候用到了这种算法)

题目解析

1.移动零https://leetcode.cn/problems/move-zeroes/description/https://leetcode.cn/problems/move-zeroes/description/

题目描述:

将全部的0移动到数组最后,且其他元素的相对位置保持不变

算法原理:数组划分

我们的目的是将数组分为两个区间 一个是非0区间,一个是0并且非零元素的相对位置不变,最直接的方法是遍历移动,即遇到0我们去找下一个非0然后将这两个元素进行位置交换

那么我们可以使用两个指针:1.cur 扫描遍历数组 2.dest:已经处理的区间内,非零元素的最后一个位置

【0,dest】都是非0   【dest+1,cur-1】都是0

cur遇到非0停止,将cur与dest+1进行交换,然后cur++,dest++


代码实现:

public void moveZeroes(int[] nums) {int cur=0,dest=-1;while(cur<nums.length){if(nums[cur]!=0){dest++;int tmp=nums[dest];nums[dest]=nums[cur];nums[cur]=tmp;}cur++;}}

2.复写0

https://leetcode.cn/problems/duplicate-zeros/description/

题目描述

给定一个长度固定的数组,将每个零复写一遍,并将其余元素向右平移

算法原理

如果我们从左向右的进行复写的话,这会导致我们的0覆盖掉本来应该存在的数,所以我们从右向左进行复写,从右向左复写的时候我们要先找到最后一个需要复写的数,因此我们的大体流程分为两步:1.找到最后一个复写的数  2.然后从右向左进行复写操作

注意实现:

1.如何找到最后一个要复写的数?
 当cur<n的时候,一直进行以下循环   :
如果nums【cur】==0,dest+2,不是的话dest+1
如果dest到结束位置就结束循环
如果没有cur++继续判断

2.判断dest是否越界到n的位置

如果越界的话,执行下面几步:1.n-1改成0  2.cur向前移动一步  3.dest 向前移动两步

代码实现

1.先找到最后一个要复写的数

2.“从后向前”完成复写操作

 public void duplicateZeros(int[] arr) {int cur=0,dest=-1,n=arr.length;while(cur<n){if(arr[cur]==0){dest+=2;}else{dest++;}if(dest>=n-1){break;}cur++;}if(dest==n){arr[n-1]=0;dest-=2;cur--;}while(cur>=0){if(arr[cur]!=0){arr[dest--]=arr[cur--];}else{arr[dest--]=0;arr[dest--]=0;cur--;}}}

3.快乐数

https://leetcode.cn/problems/happy-number/description/

题目描述

什么是快乐数?

每一次将这个数替换成每个位置上的数的平方和,最后能变成1的正整数

算法原理

因为这个要么是最后变为1,要么会进入一个循环,所以我们要做的是判断环是否存在

如果题目没有告诉我们会进入循环,我们如何能判断有环的存在呢?

这会利用到鸽巢原理(抽屉原理)(n个巢,(n+1)个鸽子,至少有一个鸽巢中鸽子数大于1)

判断环的存在我们已经很熟悉了,用到快慢指针

代码实现

 public boolean isHappy(int n) {int slow=n,fast=bitSum(n);while(slow!=fast){slow=bitSum(slow);fast=bitSum(bitSum(fast));}if(slow==1){return true;}else{return false;}}public int bitSum(int n){int sum=0;while(n!=0){int s=n%10;sum+=s*s;n/=10;}return sum;}

4.盛最多水的容器

https://leetcode.cn/problems/container-with-most-water/description/

题目描述

给定一个长度为n的整数数组height有n条垂线,第i条最大高度为数组内对应下标的数

目标:找出其中两条线,使他们与x轴共同构成的容器可以容纳最多的水(不能倾斜容器(木桶效应))

算法原理

解法一:暴力枚举(两层for循环) 时间复杂度过高

解法二:在暴力枚举的基础上进行优化,v=sh,(s相当于数组下标的差,h为两条线对应的最小值)

我们在数组两端固定left,right先算出此时的v,并记录

然后比较left和right对应的值,如果left大,right左移;如果right大,left右移

代码实现

 public int maxArea(int[] h) {int left=0,right=h.length-1;int ret=0;while(left<right){int v=Math.min(h[left],h[right])*(right-left);ret=Math.max(ret,v);if(h[left]<h[right]){left++;}else{right--;}}return ret;}

http://www.dtcms.com/a/482178.html

相关文章:

  • ubuntu2404系统安装nocobase的方法
  • FFmpeg 播放播放 HTTP网络流读取数据过程分析
  • 使用Spring Boot构建系统安全层
  • 项目1:高分辨率(1920 * 1080)编码码流推送流媒体讲解
  • [嵌入式系统-109]:GPU与NPU的比较
  • 算法入门:专题攻克一---双指针4(三数之和,四数之和)强推好题,极其锻炼算法思维
  • 比较好的网页设计网站wordpress salient 8
  • 建设网站都需要哪些资料佛山做网站的公司
  • 198种组合算法+优化CNN卷积神经网络+SHAP分析+新数据预测+多输出!深度学习可解释分析,强烈安利,粉丝必备!
  • 深度学习基础模块
  • 仿muduo库的高并发服务器
  • DNS优选 2.8.2 | 优选最快DNS,访问受限网站,去网站广告
  • 网络编程就是做网站么枣庄网页制作公司
  • 【目标跟踪n雷达二维EKF】雷达对单目标跟踪,滤波(使用扩展卡尔曼)增强定位能力,二维,目标状态未知,雷达数量可调。给出MATLAB代码
  • 从鉴酱酒:传承文化,品味佳酿
  • 响应式网站开发图标wordpress 注册 登陆不了
  • 如何在 MySQL 中实现慢查询监控
  • Python 切片的核心概念
  • Linux用户空间/内核空间获取用户空间地址的页表
  • AB Download Manager(下载管理工具) 中文绿色版
  • 深圳建设网站公司排名网页制作作业网站
  • Python3 AI 编程助手
  • C# WPS操作PPT,全屏,缩率图,备注,跳转播放
  • 医药公司网站建设备案网站做戒酒通知书
  • 高效存储大List对象到Redis的解决方案,使用分片存储和压缩技术
  • 阿德莱德学习推理与导航!PEAP-LLM:基于大语言模型的参数高效动作规划
  • 科技赋能畜牧业|小吉快检 BL-08plus 推动行业数字化转型
  • Qt多线程渲染架构设计与实现思考
  • 亚马逊云科技 WAF 指南(十)用 Amazon Q Developer CLI 解决 DDoS 防护与 SEO 冲突问题
  • 网络营销是什么 能做什么seo项目经理