主要的方法有:
- 对于单个数组的双指针,特别的头尾指针,特别对于排序数组,或者其他情况。主要的目的是,不同的情况,只有一个指针移动,而且两个指针移动方向相对,指针最后对撞,遍历结束。(比如,15.三数之和的问题,11.盛最多水的容器,75. 颜色分类,881. 救生艇。)
- 对于两个数组,特别是字符串的比较问题。多是在每一个字符串有一个指针,总共两个指针。这种问题主要考虑指针是从头开始,还是从尾部开始,多数有趣的题是从尾部开始。(比如,844. 比较含退格的字符串,面试题10.01 合并排序的数组,面试题17.11. 单词距离)
- 链表的双指针,这个是比较套路的问题,常见的有链表反转、倒数第k个节点的寻找、快慢指针等。(比如,234. 回文链表,19. 删除链表中的倒数第N个节点,141. 环形链表,142.环形链表II,457. 环形数组循环。)在链表中使用多指针,特别是涉及节点位置改变的时候,需要注意特殊情况下指针之间的相邻等情况,比如 面试题 02.04. 分割链表
- 哈希表的使用,对于一些寻找数组或者字符串中符合特定运算指标的元素,这种问题非常适合用哈希表来解决,可以实现O(N)级别的时间复杂度。特别的,对于涉及连续子串和,特定类型数据个数的问题,可能使用前缀和结合哈希。(比如,1248. 统计优美子数组,1658. 将x减到0 的最小操作数。)
5.滑动窗口,经典的双指针问题,主要用来解决寻找满足某一条件的连续子串问题。左右指针维护一个窗口,右指针往右窗口扩大,左指针往右窗口滑动。(比如,424. 替换后的最长重复字符,1004. 最大连续1的个数 III) - 相邻指针,面试题17.11 单词距离,面试题16.06. 最小差,分别在两个有序列表中各自维护一个指针,逐步更新指向较小值的指针。 (等同于先将两个有序列表合并为一个大的有序了列表,在同一个有序列表中维护了两个指针,使该两个指针之间的距离尽可能小)。有一个类似的题目:632. 最小区间,这个是很多个列表,各自维护一个指针,更新时向右移动指向的数最小的指针。
- 循环数组,在原有列表基础上再串联一个原有列表+循环周期。这样可以实现和列表完全相同的滑动移动。如题1610. 可见点的最大数目
困难题,解题思路比较特别的:
(1)992. K 个不同整数的子数组
题解:https://leetcode-cn.com/problems/subarrays-with-k-different-integers/solution/hua-dong-chuang-kou-by-zhangfuzuo-3/
(2)30. 串联所有单词的子串
题解:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/solution/hua-dong-chuang-ha-xi-biao-onon-by-zhangfuzuo/
(3)面试题 17.21. 直方图的水量 这个是完全看别人代码写的, 代码很简洁
(4)828. 统计子串中的唯一字符
这道题的解法也非常巧妙,题解:https://leetcode-cn.com/problems/count-unique-characters-of-all-substrings-of-a-given-string/solution/onon-by-zhangfuzuo/