算法专题——双指针

目录

前言

1、移动0

2、复写零

3、快乐数

4、盛最多水的容器

5、有效三⻆形的个数

6、和为s的两个数字 

7、三数之和 

8、四数之和


前言

本文主要介绍一些用到双指针的常见算法题。


1、移动0

链接:https://leetcode.cn/problems/move-zeroes/description/

本题为数组分隔、数组分块问题,常见解法是使用双指针。

定义两个指针分别为cur和dest,将该数组划分为三个部分。使用cur遍历数组,cur前代表处理完的数据,cur后代表待处理的数据。dest前代表非0数字,dest后为0数字。

n为数组长度,数据会被划分为三个区间,[0,dest]为处理后非零,[dest+1,cur-1]为处理后0,[cur,n-1]为待处理。

执行逻辑:cur在从前向后遍历的过程中,如果遇到0将该元素留在第二个区间 cur++,如果遇到非0证明要把该元素换到第一个区间则dest++,置换nums[cur]和nums[dest]后cur++。

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

扩展:该思想同样适用于快排,快排时会找到一个标志数temp,要求temp左边的元素小于ntemp,右边的元素大于temp。和左边非0右边0其实是一样的,只需要替换if中的条件即可。

2、复写零

链接:https://leetcode.cn/problems/duplicate-zeros/submissions/588110496/

本题虽然显示是简单,但是非常难,先根据异地移动思考,转化为就地操作。从前往后遍历会出问题,所以从后往前遍历,先要确定好cur的位置,画图做,很难想。

class Solution {public void duplicateZeros(int[] arr) {int cur=0,dest=0;int n=arr.length;//找到开始反向操作的节点while(cur<=n){//到末尾处会出现两种情况if(dest==n){cur--;dest--;break;}if(dest==n+1){arr[dest-2]=0;dest-=3;cur-=2;break;}if(arr[cur]!=0){dest++;}else{dest+=2;}cur++;}//开始反向遍历while(cur>=0){       if(arr[cur]!=0){arr[dest]=arr[cur];cur--;dest--;}else{arr[dest--]=0;arr[dest--]=0;cur--;}}}
}

3、快乐数

链接:https://leetcode.cn/problems/happy-number/

本题有两种情况,一种是变成1,另一种是无限循环,也就是说某次计算后变成了之前出现过的数字。1再经过计算后还是1,所以这也可以看做是一种循环。所以本题最后的结果可以看作两种循环,一种循环里没有1,一种循环里全是1,我们只要判断循环里是否有1就行了。那么第一步就是进入到循环,在hot100中有一道环形链表的题,通过那到题的思路我们可以想到,想要进入到循环要使用快慢指针。

class Solution {//定义一个计算一个数各位平方和的函数public int bit_square(int n) {int sum=0;while(n!=0){int m=n%10;sum+=m*m;n=n/10;}return sum;}public boolean isHappy(int n) {int slow=n;int fast=bit_square(n);while(slow!=fast){slow=bit_square(slow);fast=bit_square(bit_square(fast));}if(slow==1){return true;}else{return false;}}
}

4、盛最多水的容器

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

这道题首先想到的是用暴力求解法,也就是遍历一遍,把所有的值计算一边找出最大的,但这样做会超时。然后我们可以尝试找一下规律,发现计算两个位置的体积后,那个高度较小的位置与这两个位置之间的任何位置的体积都比原来小。所以我们直接选择两个端点,在计算后高度较小的那个数直接排除掉,向左和向右平移即可。 

class Solution {public int maxArea(int[] height) {int left=0,right=height.length-1,res=0;while(left<right){int volume=(right-left)*Math.min(height[left],height[right]);res=Math.max(volume,res);if(height[left]<height[right]){left++;}else{right--;}}return res;}
}

5、有效三⻆形的个数

链接:https://leetcode.cn/problems/valid-triangle-number/submissions/588461959/

解法一:暴力求解

用暴力求解可以遍历所有的可能,然后把满足要求的加到一起,时间复杂度为N^3.

解法二:双指针

三角形的判定条件为两边之和大于第三边,我们没必要判别三次,只要保证最小的两条边大于第三边即可,这样只需要判别一次,所以在最开始先给数据排序。

class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int count=0;//从数组最右侧开始遍历,每次把数组的最右侧设为标志位,判断剩下的数里有多少种两个数的组合和它能构成三角形for(int i=nums.length-1;i>=2;i--){int left=0,right=i-1;while(left<right){//如果此时满足是大于,那么left和right中间的的数和right处的数构成的组合也一定满足要求if(nums[left]+nums[right]>nums[i]){count+=right-left;right--;}else{//如果此时是小于,那么left和right中间的的数和left处的数构成的组合一定不满足要求left++;}}}return count;}
}

 使用双指针时间复杂度为N^2。

6、和为s的两个数字 

链接:https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/description/ 

本题题目已经说了升序,用双指针可以很轻松的做出来。

class Solution {public int[] twoSum(int[] price, int target) {int left=0,right=price.length-1;while(left<right){if(price[left]+price[right]==target){return new int[]{price[left],price[right]};}else if(price[left]+price[right]>target){right--;}else{left++;}}return new int[2];//照顾编译器,必须有返回值}
}

7、三数之和 

链接:https://leetcode.cn/problems/3sum/

 借助上一道题两数之和的思想,这道题可以类比。我们可以先排序(方便去重,数组里只要保存着相同的元素就算顺序不一样也算重复),然后固定最开始的元素作为数a,然后从后面找两个数的和等于a的相反数,就转化为了两数之和。然后取第二个数为数a,再找后面的相加为a的相反数的两个数,重复这个操作。

这道题注意要去重,找到⼀个结果之后, left 和 right 指针要跳过重复的元素,当使⽤完⼀次双指针算法之后,固定的 a 也要跳过重复的元素。

8、四数之和

链接:https://leetcode.cn/problems/4sum/

结合三数之和和两数之和的思想,可以很轻松的做出来,这道题有个坑是他弄了一个很大的数,所以需要用long来存。

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> res=new ArrayList<>();Arrays.sort(nums);int n=nums.length;for(int i=0;i<=n-4;){long target1=target-nums[i];for(int j=i+1;j<=n-3;){int left=j+1,right=n-1;long target2=target1-nums[j];while(left<right){long sum=nums[left]+nums[right];if(sum<target2){left++;}else if(sum>target2){right--;}else{res.add(new ArrayList(Arrays.asList(nums[left],nums[right],nums[i],nums[j])));left++;right--;while(nums[left-1]==nums[left]&&left<right){left++;}while(nums[right+1]==nums[right]&&left<right){right--;}}}j++;while(nums[j-1]==nums[j]&&j<=n-3){j++;}}i++;while(nums[i-1]==nums[i]&&i<=n-4){i++;}}return res;}
}


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

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

相关文章

Spark任务的执⾏流程

Spark 任务的执行流程涉及多个组件和步骤的协同工作&#xff0c;以下是其详细的执行流程&#xff1a; 提交任务 编写应用程序&#xff1a;用户首先使用 Spark 支持的编程语言&#xff08;如 Scala、Java、Python 等&#xff09;编写 Spark 应用程序&#xff0c;在应用程序中定…

人工智能与云计算的结合:如何释放数据的无限潜力?

引言&#xff1a;数据时代的契机 在当今数字化社会&#xff0c;数据已成为推动经济与技术发展的核心资源&#xff0c;被誉为“21世纪的石油”。从个人消费行为到企业运营决策&#xff0c;再到城市管理与国家治理&#xff0c;每个环节都在生成和积累海量数据。然而&#xff0c;数…

动态规划——状态压缩

状态压缩简介 状态压缩指的是&#xff0c;通过一串0-1码保存一个集合的状态&#xff0c;把一个集合压缩成一个整数&#xff0c;所以称为状态压缩。 例如&#xff0c;有一行棋子&#xff0c;它们的排列分别是&#xff1a;黑 白 白 黑 黑 白 黑 白 这就可以用10011010 ( 2 ) _{…

【Chrome Extension】一、CSDN计时扩展设计

【Chrome Extension】一、CSDN计时扩展设计 重点内容内容脚本 content_scripts 文件目录1、整体目录2、manifest.json3、scripts/content.js4、css/content.css 重点内容 内容脚本 content_scripts 1、manifest.json文件配置 {"manifest_version": 3, # *依赖Chro…

C中设计不允许继承的类的实现方法是什么?

在C中&#xff0c;设计不允许继承的类可以通过多种方法实现。以下是详细的方法说明及示例&#xff1a; ### 方法一&#xff1a;将构造函数和析构函数设为私有 这种方法的核心思想是通过将构造函数和析构函数设为私有&#xff0c;使得子类无法调用这些函数&#xff0c;从而无法…

javaEE-线程的常用方法-4

目录 一.start():启动一个线程 调用start()方法 start()方法只能调用一次&#xff1a; java中的API: start()和run()的区别: 二.中断一个线程 中断线程方法1:引入标志位 中断线程方法2:调⽤interrupt()⽅法 抛出的异常: 三.等待一个线程 join() 四、获取线程引用 五…

AI的进阶之路:从机器学习到深度学习的演变(四)

AI的进阶之路&#xff1a;从机器学习到深度学习的演变&#xff08;三&#xff09; 五、深度学习的应用领域 深度学习的应用领域广泛&#xff0c;涵盖了计算机视觉、自然语言处理、语音识别和推荐系统等多个方面。以下将详细探讨这些关键应用领域&#xff0c;展示深度学习在不同…

Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)

Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版) 文章目录 Kubeadm+Containerd部署k8s(v1.28.2)集群(非高可用版)一.环境准备1.服务器准备2.环境配置3.设置主机名4.修改国内镜像源地址5.配置时间同步6.配置内核转发及网桥过滤二.容器运行时Containerd安装(所有节点)…

dockerfile文档编写(3):构建失败后清理缓存(删除容器和镜像相关命令)

目录 删除所有强制删除所有容器强制删除所有镜像 有的时候想要修改项目&#xff0c;发现说空间不够了&#xff0c;那就需要清理一下docker存储空间了 删除所有 如果没有什么其他的项目的话&#xff0c;比较快捷和方便 强制删除所有容器 docker rm -f $(docker ps -aq)强制删…

圣诞快乐(h5 css js(圣诞树))

一&#xff0c;整体设计思路 圣诞树h5&#xff08;简易&#xff09; 1.页面布局与样式&#xff1a; 页面使用了全屏的黑色背景&#xff0c;中央显示圣诞树&#xff0c;树形由三层绿色的三角形组成&#xff0c;每一层的大小逐渐变小。树干是一个棕色的矩形&#xff0c;位于三角…

PostgreSQL和Postgis安装

Windows下PostgreSQL和对应的版本的Postgis安装 PostgreSQL安装 1、官网下载地址 https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 2、根据自己的系统下载完成&#xff0c;Windows下可以直接傻瓜式安装就OK 建议不要通过自带的这个程序安装postgis,…

拒绝 Helm? 如何在 K8s 上部署 KRaft 模式 Kafka 集群?

首发&#xff1a;运维有术 今天分享的主题是&#xff1a;不使用 Helm、Operator&#xff0c;如何在 K8s 集群上手工部署一个开启 SASL 认证的 KRaft 模式的 Kafka 集群&#xff1f; 本文&#xff0c;我将为您提供一份全面的实战指南&#xff0c;逐步引导您完成以下关键任务&a…

面向微服务的Spring Cloud Gateway的集成解决方案:用户登录认证与访问控制

&#x1f3af;导读&#xff1a;本文档详细描述了一个基于Spring Cloud Gateway的微服务网关及Admin服务的实现。网关通过定义路由规则&#xff0c;利用负载均衡将请求转发至不同的后端服务&#xff0c;并集成了Token验证过滤器以确保API的安全访问&#xff0c;同时支持白名单路…

牛客网 SQL36查找后排序

SQL36查找后排序 select device_id,age from user_profile order by age asc #select [字段1,字段2] from [表名] order by [字段1] [升序(asc)/降序(desc)],[字段2] [升序(asc)/降序(desc)] #select&#xff1a;查询 #order by 排序 每日问题 如何实现对象的克隆&#xff1…

备忘一个FDBatchMove数据转存的问题

使用FDBatchMove的SQL导入excel表到sql表&#xff0c;设置条件时一头雾水&#xff0c;函数不遵守sql的规则。 比如替换字段的TAB键值为空&#xff0c;replace(字段名,char(9),)竟然提示错误&#xff0c;百思不得其解。 试遍了几乎所有的函数&#xff0c;竟然是chr(9)。 这个…

C++的封装(十四):《设计模式》这本书

很多C学习者学到对C语言有一定自信后&#xff0c;会去读一下《设计模式》这本书。希望能够提升自己的设计水平。 据我所知&#xff0c;围绕C语言出了很多书。因为正好赶上泡沫经济时代。大家一拥而上&#xff0c;自己半懂不懂就出书&#xff0c;抢着出书收割读者&#xff0c;出…

TransmittableThreadLocal线程变量传递问题

ThreadLocal有时挺好用的&#xff0c;但是在某些情况下需要将父线程中的本地变量传递给子线程时&#xff0c;这个就不行了。 那么TransmittableThreadLocal就是为了解决这个问题的&#xff0c;但是&#xff0c;如果在某些异步的场景中&#xff0c;特别是异步线程是下载文件等耗…

浅析InnoDB引擎架构(已完结)

大家好&#xff0c;我是此林。 今天来介绍下InnoDB底层架构。 1. 磁盘架构 我们所有的数据库文件都保存在 /var/lib/mysql目录下。 由于我这边是docker部署的mysql&#xff0c;用如下命令查看mysql数据挂载。 docker inspect mysql-master 如下图&#xff0c;目前只有一个数…

Ajax中的axios

既然提到Ajax&#xff0c;那就先来说一说什么是Ajax吧 关于Ajax Ajax的定义 Asynchronous JavaScript And XML&#xff1a;异步的JavaScript和XML。 反正就是一句话总结&#xff1a; 使用XML HttpRequest 对象与服务器进行通讯。 AJAX 是一种在无需重新加载整个网页的情况下&…

苹果手机怎么清理空间:拯救你的拥挤手机

在数字生活的海洋中&#xff0c;我们的苹果手机就像一艘小船&#xff0c;载满了照片、应用、视频和各种下载的“宝贝”。随着时间的推移&#xff0c;这艘小船开始变得拥挤&#xff0c;航行速度放缓&#xff0c;甚至有时候直接卡壳。苹果手机怎么清理空间&#xff1f;是时候学会…