双指针

专题-双指针

  • 双指针问题无论在笔试还是面试中出现的频率都非常高;是性价比非常高的一类问题。

模板小结

RoadMap

Index

首尾双指针

两数之和

LeetCode/167. 两数之和 II - 输入有序数组arrow-up-right

问题描述(167. 两数之和 II - 输入有序数组)

拓展

  • 如果存在多个答案,并要求输出所有不重复的可能

    三数之和

思路 1

  • 首尾双指针

  • 因为是有序的,可以尝试使用首尾双指针解决该问题,时间复杂度为 O(N)

  • Python(双指针)

思路 2

  • 本题还可以利用 Hash 表解决,时间复杂度 O(N),空间复杂度 O(N)

  • 使用 Hash 表不要求数组有序

    LeetCode/1. 两数之和arrow-up-right

  • Python(Hash)

三数之和

LeetCode/15. 三数之和arrow-up-right

问题描述

思路

  • 排序 + 首尾双指针

  • 将第三个数当作前两个数的目标和,在两数之和的基础上套一层循环

  • 难点在于如何去重(不借用 set)

python

N 数之和

LeetCode/18. 四数之和arrow-up-right

题目描述(四数之和)

Python(N 数之和)

最接近的三数之和

LeetCode/16. 最接近的三数之和arrow-up-right

问题描述

思路

  • 排序 + 双指针

Python

两数之和 - 小于等于目标值的个数

LintCode/609. 两数和-小于或等于目标值arrow-up-right

此为收费问题:LintCode 练习-609. 两数和-小于或等于目标值arrow-up-right - CSDN博客

问题描述

思路

  • 排序 + 首尾双指针

python

代码说明

  • [2,7,11,15] 为例

时间复杂度

  • O(NlogN) + O(N) = O(NlogN)

三数之和 - 小于等于目标值的个数

LintCode/918. 三数之和arrow-up-right

问题描述

思路

  • 排序 + 双指针

Python

三角形计数(Valid Triangle Number)

LeetCode/611. 有效三角形的个数arrow-up-right

问题描述

思路

  • 排序 + 首尾双指针

  • 相当于两数之和大于目标值的个数

Python

接雨水(Trapping Rain Water)(一维)

LeetCode/42. 接雨水arrow-up-right

问题描述

思路 1

  • 一个简单的方法是遍历两次数组,分别记录每个位置左侧的最高点和右侧的最低点

  • C++

思路 2

  • 双指针,遍历一次数组

  • Python

盛最多水的容器(Container With Most Water)

LeetCode/11. 盛最多水的容器arrow-up-right

问题描述

思路

  • 首尾双指针

Python

反转字符串(Reverse String)

LeetCode/344. 反转字符串arrow-up-right

问题描述

思路

  • 首尾双指针

Python

颜色分类(Sort Colors)

LeetCode/75. 颜色分类arrow-up-right

问题描述

思路

  • 首尾双指针

    • l 记录最后一个 0 的位置

    • r 记录第一个 2 的位置

    • i 表示当前遍历的元素

Python

同向双指针

数组中的最长山脉(Longest Mountain in Array)(同向双指针)

LeetCode/845. 数组中的最长山脉arrow-up-right

问题描述

思路 - 同向双指针

  • 同向双指针(滑动窗口),只需遍历一遍数组

Python

最小覆盖子串(Minimum Window Substring)

LeetCode/76. 最小覆盖子串arrow-up-right

问题描述

思路

  • 同向双指针 + HaspMap

Python

长度最小的子数组(Minimum Size Subarray Sum)

LeetCode/209. 长度最小的子数组arrow-up-right

问题描述

思路

  • 同向双指针

Python

无重复字符的最长子串(Longest Substring Without Repeating Characters)

LeetCode/3. 无重复字符的最长子串arrow-up-right

问题描述

思路

  • 同向双指针 + Hash 表

Python

水果成篮(Fruit Into Baskets)

LeetCode/904. 水果成篮arrow-up-right

问题描述

思路

  • 题目大意:寻找一个最大的子区间,该子区间中只包含两种元素(无顺序要求)

  • 同向双指针

Python

反向双指针

数组中的最长山脉(Longest Mountain in Array)(反向双指针)

LeetCode/845. 数组中的最长山脉arrow-up-right

问题描述

思路 - 反向双指针

  • 先找到“山峰”,然后向两侧移动指针,寻找左右“山脚”

  • 极端情况下,可能会遍历两次数组(左指针有一个回溯的过程)

Python

最长回文子串(Longest Palindromic Substring)

LeetCode/5. 最长回文子串arrow-up-right

问题描述

思路

  • 搜索最长回文子串的方法很多;最主要的是动态规划和双指针方法

    这两种方法的时间复杂度都不是最优的, O(N^2);此外还存在 O(NlogN)O(N) 方法,但是这些方法并不存在普适性

    ./动态规划/最长回文子串arrow-up-right

  • 这里介绍的使用双指针的方法;

  • 值得注意的一点是,回文子串的长度可能为奇或偶:一个简单的处理方法是对每个位置都判断奇偶两种情况

Python

分离双指针

实现 strstr()

LeetCode/28. 实现strStr()arrow-up-right

问题描述

思路

双指针

KR 算法

两个数组的交集(Intersection of Two Arrays)

I

LeetCode/349. 两个数组的交集arrow-up-right

问题描述

思路

  • 1)排序 + 二分

  • 2)Hash

  • 3)排序 + 双指针

Python(双指针)

II

LeetCode/350. 两个数组的交集 IIarrow-up-right

问题描述

思路

  • 相比 1 少了一个去重的步骤

进阶

Python

合并两个有序数组(Merge Sorted Array)

LeetCode/88. 合并两个有序数组arrow-up-right

问题描述

思路

  • 从后往前遍历

Python

链表相关

分隔链表(Partition List)

LeetCode/86. 分隔链表arrow-up-right

问题描述

思路

  • 链表快排的中间操作;

  • 新建两个链表,分别保存小于 x 和大于等于 x 的,最后拼接;

  • 因为要求节点的相对位置不变,所以这么写比较方便;

  • 一般来说,链表快排有两种写法:一种是交换节点内的值,一种是交换节点;该写法适用于后者。

  • 如果是用在链表快排中,可以把头节点作为 x,最后把 x 插进 lo 和 hi 链表的中间;

  • 这种写法不适合用在链表快排中,因为这里有拼接操作;

  • 在实际链表快排中 partition 操作只对中间一部分执行,如果需要拼接,容易出错。

Python

链表排序(Sort List)

链表快排

./数据结构/链表快排arrow-up-right

链表归并

./数据结构/链表归并arrow-up-right

链表插入排序

./数据结构/链表插入排序arrow-up-right

链表选择排序

./数据结构/链表选择排序arrow-up-right

链表冒泡排序

./数据结构/链表冒泡排序arrow-up-right

旋转链表(Rotate List)

./数据结构/旋转链表arrow-up-right

其他

最小区间(Smallest Range)

LeetCode/632. 最小区间arrow-up-right

问题描述

思路

  • 最小堆

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) # 最小堆

```

最后更新于

这有帮助吗?