双指针解题秘籍:从入门到精通

在开始讲题目之前,要介绍一下这类题目的整体思路,双指针的题目和滑动窗口的题目很像,都是通过两个指针进行移动来解决问题,只不过滑动窗口是两个指针往同一个方向移动,而双指针是两个指针从左右两边往中间移动

双指针的很多题目都需要借助单调性来解决问题,单调性则是通过暴力解法推导出来的

1.移动零

题目来源:283. 移动零 - 力扣(LeetCode)

2.复写零

题目来源:1089. 复写零 - 力扣(LeetCode)

3.快乐数

题目来源:202. 快乐数 - 力扣(LeetCode)

题目给的信息帮我们大大降低了题目的难度,这个数最后只有两种可能,无限循环不为1,或者最后是1

我们以19和2来分别画图分析

这是19的分析过程

这是2的分析过程,可以发现。到最后2成环了

这个图就有点像之前学过的链表成环问题了元素,当最后都是一时,相当于也是成了一个环,所以,这道题就相当于有两种成环的链表,一个环里的元素都是1,一个环里的元素不为1,所以,这个问题就转化成了,判断环里元素是不是1。

我们假设链表成环,那么我们一定可以用快慢指针来检验,并且快慢指针一定会在环中相遇

因此,只要来判断相遇时的元素是不是1就好了

接下来开始实现代码

4.盛最多容器的水

题目来源:11. 盛最多水的容器 - 力扣(LeetCode)

看题目可能不太好理解,看图就可以理解了,目的就是要装最多的水

我们可以用图来分析

最简单的方法就是暴力枚举,找到最大的容量,但时间复杂度可能会太大了,也可能会超时

我们需要来找一个更巧妙的方法

我们先定义一个max,来储存可能最大的值,如果新的容量大于max,就把max更新为新的容量

用两个指针来控制左右的区间,以开头为左区间,结尾为右区间

先固定一个边界,比如,先将左边界固定,那么右边界就是可以动的,在右边界向内缩小的过程中,宽度是一直在减小的,假如右边界的高度大于等于左边界,那么高度不变;假如右边界的高度小于左边界,高度减小,不管怎么说,容量都是在减小的。

所以说,更新的边界需要是较小的那一个,这样才能够给高度带来变化的可能性

当两个变价相遇时,循环就结束了

接下来,来实现一下

5.有效三角形的个数

题目来源:611. 有效三角形的个数 - 力扣(LeetCode)

一开始想到的方法肯定都是暴力枚举,写三层循环,来找可能的三角形个数,但这样效率太慢了

我们来用一种更巧妙的解法,双指针

在开始找个数之前,我们可以先用排序来优化一下效率

我们都知道,三角形可以成立的条件是任意两边之和大于第三边

那么,假如,我们可以直接看一下,较小的两个数之和是否大于第三个数,就可以只判断一次

并且,将数组先进行排序,就能够让我们使用接下来的一种方法

我们可以用双指针来完成这道题目,用一个数组来进行举例

先选取最大数为一条边,然后分别选取剩下的数中的最大数和最小数为right和left

假如left和right加起来大于max说明能组成三角形,并且因为数组是排好序的,所以left右边的数也一定能够和right和max组成三角形,因此,我们让right--;假如left和right加起来小于等于max,说明不能组成三角形,并且,如果right是右边的任何数,都不可能与left的和大于max,所以,我们需要让left++;

当right-left<1时循环停止,进行下一次循环,max这个下标的最小值是2.

接下来开始实现代码

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

题目来源:LCR 179. 查找总价格为目标值的两个商品 - 力扣(LeetCode)

这道题的思路跟找有效三角形的个数那题类似,暴力解法肯定可以,但是可以利用单调性来降低复杂度

因为价格是排升序的,我们一开始定义两个指针,一个指向开头一个指向末尾,判断两数之和与目标值的关系

如果大于目标值,那么right--;

如果小于目标值,left++;

如果等于,跳出循环;

最后将下标为left和right的元素放进数组就好了

7.两数之和

题目来源:1. 两数之和 - 力扣(LeetCode)

这道两数之和跟后面的三数之和,四数之和有关系,可以说这题是那两题的基础

我们先用示例1来分析

设置两个指针从左右两边往中间走,当两个数之和大于目标值时,让右边那个指针--

当两个数之和小于目标值时,让左边那个指针++

一直找,最后就能够找到我们要的结果了

8.三数之和

题目来源:15. 三数之和 - 力扣(LeetCode)

三数之和的写法有借鉴前面的两数之和

先来分析一下题目,题目的要求是从容器中找到三个数之和等于0,我们可以换个思路来想,可以先固定一个数x,从剩下的数来找到和为-x的两个数

并且题目的要求是三元组不能重复,意味着不能有相同的三个数组成顺序不同的组

可以通过示例来观察

第一个和第二个结果都为0,但是只取其中一组

所以在完成该题的过程中,我们需要注意去重和边界问题

9.四数之和

题目来源:18. 四数之和 - 力扣(LeetCode)

四数之和的思路与三数之和基本类似,只不过外面多了一层循环

与三数之和相同,先对数组排序

我们以例1进行举例

我们需要找到四个数,使得这四个数之和等于目标值target

首先,我们将i固定在第一个位置,然后将j固定在i的下一个位置,然后让left在j的下一个位置,right在最后一个位置

一开始我需要找到四个数之和等于target,相当于target=numsi+numsj+numsleft+numsright

也就是说,我们要找到三个数的和等于target-numsi

继续往下推,就是要找到两个数之和等于numsleft+numsright

具体的思路与前面差不多,最重要的是,我们需要注意两个点和一种特殊情况

第一个点:越界,我们需要在每一个子循环检查是否越界

第二个点:去重,我们需要将重复的情况去除掉,因为我们是排好序的,所以这一点比较容易就可以做到了

特殊情况指的是假如数组的元素小于四,那么如果按照上述的思路就会导致越界,所以需要进行特殊的处理

以上就是本篇文章的全部内容了,如果对你有帮助,可以点个赞支持一下,感谢各位的观看

https://gitee.com/mo-ran-qingyun

这是我个人的gitee仓库,账号上文章的代码都会发到仓库里,有兴趣可以看一下

相关推荐
千里码aicood1 小时前
面向电商冷启动与数据稀疏性的协同过滤算法优化研究
大数据·算法·协同过滤
代码中介商1 小时前
C++ 预约系统实战(一):项目总览与 C/S 架构设计
c语言·开发语言·c++
能源革命1 小时前
TimesFM(Time Series Foundation Model)介绍
算法·能源
猎嘤一号1 小时前
学术训练(一)文献检索与阅读
人工智能·算法·机器学习·科研入门
弘毅 失败的 mian1 小时前
数组和指针基础
c语言·开发语言·经验分享·笔记
Doubbbbbbble云1 小时前
多路归并算法在外部排序中的实现与优化
算法
Logic1012 小时前
C语言/数据结构位运算题解:异或XOR找出地铁规划中的“独特坐标“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
沉淀的.晴天2 小时前
FreeRTOS信号量
数据结构·算法
青山木2 小时前
Hot 100 --- 打家劫舍
java·数据结构·算法·leetcode·动态规划