双指针
专题-双指针
双指针问题无论在笔试还是面试中出现的频率都非常高;是性价比非常高的一类问题。
模板小结
同向双指针

数组中,一般用于寻找满足某个条件的连续区间;
链表相关问题中经常会使用快慢双指针来寻找某个节点;
典型问题:最小覆盖子串、数组中的最长山脉(同向双指针)
反向双指针

先依次遍历都某个节点,然后使用双指针从该节点反向判断是否满足条件。
典型问题:最长回文子串、数组中的最长山脉(反向双指针)
RoadMap
Index
首尾双指针
两数之和
LeetCode/167. 两数之和 II - 输入有序数组
问题描述(167. 两数之和 II - 输入有序数组)
拓展
如果存在多个答案,并要求输出所有不重复的可能
思路 1
首尾双指针
因为是有序的,可以尝试使用首尾双指针解决该问题,时间复杂度为
O(N)Python(双指针)
思路 2
本题还可以利用 Hash 表解决,时间复杂度
O(N),空间复杂度O(N)使用 Hash 表不要求数组有序
LeetCode/1. 两数之和
Python(Hash)
三数之和
LeetCode/15. 三数之和
问题描述
思路
排序 + 首尾双指针
将第三个数当作前两个数的目标和,在两数之和的基础上套一层循环
难点在于如何去重(不借用 set)
python
N 数之和
LeetCode/18. 四数之和
题目描述(四数之和)
Python(N 数之和)
最接近的三数之和
LeetCode/16. 最接近的三数之和
问题描述
思路
排序 + 双指针
Python
两数之和 - 小于等于目标值的个数
LintCode/609. 两数和-小于或等于目标值
此为收费问题:LintCode 练习-609. 两数和-小于或等于目标值 - CSDN博客
问题描述
思路:
排序 + 首尾双指针
python
代码说明
以
[2,7,11,15]为例
时间复杂度
O(NlogN) + O(N) = O(NlogN)
三数之和 - 小于等于目标值的个数
LintCode/918. 三数之和
问题描述
思路
排序 + 双指针
Python
三角形计数(Valid Triangle Number)
LeetCode/611. 有效三角形的个数
问题描述
思路
排序 + 首尾双指针
相当于两数之和大于目标值的个数
Python
接雨水(Trapping Rain Water)(一维)
LeetCode/42. 接雨水
问题描述
思路 1
一个简单的方法是遍历两次数组,分别记录每个位置左侧的最高点和右侧的最低点
C++
思路 2
双指针,遍历一次数组
Python
盛最多水的容器(Container With Most Water)
LeetCode/11. 盛最多水的容器
问题描述
思路
首尾双指针
Python
反转字符串(Reverse String)
LeetCode/344. 反转字符串
问题描述
思路
首尾双指针
Python
颜色分类(Sort Colors)
LeetCode/75. 颜色分类
问题描述
思路
首尾双指针
l记录最后一个 0 的位置r记录第一个 2 的位置i表示当前遍历的元素
Python
同向双指针
数组中的最长山脉(Longest Mountain in Array)(同向双指针)
LeetCode/845. 数组中的最长山脉
问题描述
思路 - 同向双指针
同向双指针(滑动窗口),只需遍历一遍数组
Python
最小覆盖子串(Minimum Window Substring)
LeetCode/76. 最小覆盖子串
问题描述
思路
同向双指针 + HaspMap
Python
长度最小的子数组(Minimum Size Subarray Sum)
LeetCode/209. 长度最小的子数组
问题描述
思路
同向双指针
Python
无重复字符的最长子串(Longest Substring Without Repeating Characters)
LeetCode/3. 无重复字符的最长子串
问题描述
思路
同向双指针 + Hash 表
Python
水果成篮(Fruit Into Baskets)
LeetCode/904. 水果成篮
问题描述
思路
题目大意:寻找一个最大的子区间,该子区间中只包含两种元素(无顺序要求)
同向双指针
Python
反向双指针
数组中的最长山脉(Longest Mountain in Array)(反向双指针)
LeetCode/845. 数组中的最长山脉
问题描述
思路 - 反向双指针
先找到“山峰”,然后向两侧移动指针,寻找左右“山脚”
极端情况下,可能会遍历两次数组(左指针有一个回溯的过程)
Python
最长回文子串(Longest Palindromic Substring)
LeetCode/5. 最长回文子串
问题描述
思路
搜索最长回文子串的方法很多;最主要的是动态规划和双指针方法
这两种方法的时间复杂度都不是最优的,
O(N^2);此外还存在O(NlogN)和O(N)方法,但是这些方法并不存在普适性./动态规划/最长回文子串
这里介绍的使用双指针的方法;
值得注意的一点是,回文子串的长度可能为奇或偶:一个简单的处理方法是对每个位置都判断奇偶两种情况
Python
分离双指针
实现 strstr()
LeetCode/28. 实现strStr()
问题描述
思路
模式匹配,常见的高效算法有 KMP 算法和 Karp-Rabin(KR)算法
这里只介绍双指针方法
O(nm)和 Karp-Rabin 算法O(n+m)
双指针
KR 算法
两个数组的交集(Intersection of Two Arrays)
I
LeetCode/349. 两个数组的交集
问题描述
思路
1)排序 + 二分
2)Hash
3)排序 + 双指针
Python(双指针)
II
LeetCode/350. 两个数组的交集 II
问题描述
思路
相比 1 少了一个去重的步骤
进阶
Python
合并两个有序数组(Merge Sorted Array)
LeetCode/88. 合并两个有序数组
问题描述
思路
从后往前遍历
Python
链表相关
分隔链表(Partition List)
LeetCode/86. 分隔链表
问题描述
思路
链表快排的中间操作;
新建两个链表,分别保存小于 x 和大于等于 x 的,最后拼接;
因为要求节点的相对位置不变,所以这么写比较方便;
一般来说,链表快排有两种写法:一种是交换节点内的值,一种是交换节点;该写法适用于后者。
如果是用在链表快排中,可以把头节点作为 x,最后把 x 插进 lo 和 hi 链表的中间;这种写法不适合用在链表快排中,因为这里有拼接操作;在实际链表快排中 partition 操作只对中间一部分执行,如果需要拼接,容易出错。
Python
链表排序(Sort List)
链表快排
./数据结构/链表快排
链表归并
./数据结构/链表归并
链表插入排序
./数据结构/链表插入排序
链表选择排序
./数据结构/链表选择排序
链表冒泡排序
./数据结构/链表冒泡排序
旋转链表(Rotate List)
./数据结构/旋转链表
其他
最小区间(Smallest Range)
LeetCode/632. 最小区间
问题描述
思路
最小堆
Python
其中
l, r表示区间;i, j表示A[i][j]```python
import heapq
class Solution: def smallestRange(self, A): """ :type A: List[List[int]] :rtype: List[int] """ pq = [(row[0], i, 0) for i, row in enumerate(A)] heapq.heapify(pq) # 最小堆
```
最后更新于
这有帮助吗?

