代码手记笔录——双指针法

双指针法是数组、字符串、链表相关的题目中常用方法。包括:

  • (同向)快慢指针法
  • (同向)滑动窗口法
  • (相向)前后指针法
  • (反向)前后指针法
  • 逻辑双指针法 —— 无法归类的统一称为之
  • 补充:在双指针的基础上,添加临时指针的多指针法也视为双指针法

1、(同向)快慢指针法

快慢指针法常用在数组及链表数据结构题目中。
典型题目:

  • 19 删除链表的倒数第 N 个结点
  • 142.环形链表II

快慢指针法代码模板:

class Solution {
public:
    ListNode* ...(ListNode* head, int n) {
       ...
        ListNode *slow=dummy, *fast = dummy, *tmp;
        // 初始化fast指针比 slow 指针先走的条件
        for (int i=0; i<n; ++i) 
            fast = fast->next;
        // slow 与 fast 指针同时前进的条件 
        while (fast->next) {
            slow = slow->next;
            fast = fast->next;
        }
        ...
        return dummy->next;
    }
};

2、(同向)滑动窗口法

滑动窗口法代码模板:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        ...
        while (...) {
            ...
            while (...) {
               ...
            }
        }return ...;
    }
};

3、(相向)前后指针法

(相向)前后指针法代码模板:

class Solution {
public:
    vector<int> xxx(vector<int> &nums) {
        int p=0, q=n-1, pos=n-1;
        ...
        while (p<=q){
            if (...) {
                ...
                ++p;
            }
            else {
               ...
                --q;
            }
        }
        return ans;
    }
};

4、(反向)前后指针法

5、逻辑双指针法

典型题目:

  • 面试题 02.07. 链表相交

章节题目总结

977 有序数组的平方

此题可用的方法:

  • (相向)前后指针法
  • (反向)前后指针法

209. 长度最小的子数组

此题适合:

  • 滑动窗口法

24. 两两交换链表中的节点

此题适合:

  • (相向)前后指针法

算法思想:要交换就要指向需要交换的 2 个node,还需要 tmp 指针标记下一个 node

面试题 02.07. 链表相交

高频考题,算法思想是 p 指针走完 List A 走 List B,q 指针走完 List B 走 List A。由于二者经过的节点数相同,所以必定会指向同一位置而退出,若pqnullptr则说明不相交,否则指向的就是相交节点。

ListNode *p = headA, *q = headB;
        while (p != q) {
            // A链走完走 B链
            // B链走完走 A链
        }
 }

142.环形链表II

此题与 287 寻找重复数一起看。

高频考题,使用快慢指针。算法思想是二倍速指针 p 与一倍速指针 q在环中相遇具备如下方程关系:

a + k(b+c) + b = 2 (a+b)
=> k(b+c) = a+b
=>(k-1)(b+c) + b + c = a + b
=> (k-1)(b+c) + c = a
所以当快慢指针相遇时,再令一新指针从源头开始走,两个指针必定相遇

posted @ 2022-05-08 21:41  MasterBean  阅读(191)  评论(0)    收藏  举报