LeetCode总结 (一)双指针

  数组的双指针题型搞不好就容易翻车:指针该如何移动覆盖所有可能的情况,循环终止的边界条件、重复情形的剪枝等细节,加在一起思路就糊了,可谓是苦主。LeetCode上的双指针题型典型的有这些(标记为红色的是苦主):

  • 3. 无重复字符的最长子串阿基里斯与龟:一次遍历,前后两个指针确定长度,遇到重复则前指针放弃若干位,后指针开辟疆土)

   看似简单,实际上很坑。一个坑点是当重复的两个元素是相邻时,此时需要重置左右指针;另一个坑点是维护一个集合,里面存放当前的左右指针内所有元素;

  • 11. 盛最多水的容器 (两边交替包抄:一次遍历,左右两个指针从两边向中间推进,当然每次是放弃较小的那一边,如果移动之后数组值还变小了,则直接continue)
  • 15. 三数之和 (左指针遍历,中右包抄:O(n^2) 先排序)

    如何去重需要注意。

    另一种解法是从两边包抄,中间遍历,但是根本不对!因为每次得到一组解后,移动左指针或者右指针都有可能错过一些解!

  • 16. 最接近的三数之和左指针遍历中右包抄: O(n^2)  循环一次左边界指针,然后让中指针和右指针从两边包抄(相邻相等元素跳过从而去重))
  • 18. 四数之和(固定左边一个位置,转化为15题三数之和问题) 
  • 42. 接雨水 (左右指针追逐)

    这道题比较灵活,没套路。

    1. 取left与right两个相邻指针,如果right较大则都右移,直到left较大为止;

    2. 然后移动right,累加深度,在比left更大时把深度变现,并更新left和right;

    3. 重复2步骤,如果一直到末尾也没变现,则麻烦了,有bug;

    4. 为了解决边界bug的问题,我们将数组reverse,再运行一遍上面的步骤就好了;

    5. 为了优化计算,不用reverse,而是记录最后一次变现的位置作为哨兵,再反向遍历到哨兵位置即可。

  • 75. 荷兰国旗排序

  这道题脱离套路,从指针代表什么意义、初始化方式到移动规则,终止规则都与其他题目不同。

  • 345. 交换元音字母   左右两个指针包抄  

   

   最重要的是指针的意义

  1. 单纯用于遍历,一般是左指针,约束当前只考虑左指针在这里的情况;
  2. 左右两个哨兵,检查当前情况后移动其中某一个;
  3. 左右两个哨兵,中间一个指针遍历;
  4. 前后两个指针追逐,检查当前情况后移动其中某一个
  5. 如果不是以上套路,则原则上就是要指针每次都能移动,且覆盖所有可能的情形

  坑点:

  1. 去重:什么时候相邻两元素相同则直接跳过,这时候要注意直接跳过不会错过可能的解;

  2. 指针的意义:在整个过程中,指针代表的意义都是一致的(作为边界);作为边界一般是开区间(即第一个和最后一个元素默认为初始的指针,但是未必满足条件)

·

  

posted @ 2019-07-21 20:04  LiaoQian1996  阅读(146)  评论(0编辑  收藏  举报