0
点赞
收藏
分享

微信扫一扫

【算法】双指针问题

律楷粑粑 2022-01-04 阅读 49

当遇到链表,数组,二叉树等问题中使用

主要使用场景就是

        1.快慢指针,两个指针,一个步长大,一个步长小,或者两个指针不同步行走。适用问题有求两链表公共节点求链表中是否存在环求链表中点链表反转删除链表倒数节点

        2.对撞指针,两个指针分别指向数组的开头和结尾,通过循环来完成题目,多用于有序数组求和,或者求回文串

        3.滑动窗口,两个指针分别代表窗口的左边界和右边界,通过不断的移动左右指针来完成题目要求,多用于求连续子串或者子数列

1.快慢指针

        (1)求中点

        ListNode* fast = head;        //快慢指针都指向头结点
        ListNode* slow = head;
        while(fast!=NULL&&fast->next!=NULL){    //当快指针为奇数时判断fast->next!=NULL
            fast=fast->next->next;                //为偶数求中间靠右节点时判断fast!=NULL
            slow=slow->next;                        //快的走两步,慢的走一步
        }
        return slow;            //返回慢指针

        (2)翻转链表

        ListNode* slow = NULL;        //一开始慢节点指向空,快节点指向头结点
        ListNode* fast = head;        //这样做的好处是可以省去一些繁琐的特殊情况判断
        while(fast){        
            ListNode* next = fast->next;        //next作用是存储节点
            fast->next=slow;                //让当前节点指向自己上一个节点
            slow=fast;                        //上一个节点后移
            fast=next;                        //当前节点后移
        }
        return slow;            //此时fast为空,slow为原本节点的尾结点,翻转链表的头结点

         (3)求两链表公共节点

        ListNode* a=headA;
        ListNode* b=headB;
        while(a!=b){
            a=a->next;
            b=b->next;
            if(a==NULL&&a!=b){
                a=headB;
            }
            if(b==NULL&&a!=b){
                b=headA;
            }
        }
        if(a==NULL) return NULL;
        else    return a;
    }
    //具体解释看题解    剑指 Offer II 023. 两个链表的第一个重合节点

        (4)删除链表倒数节点

        ListNode* fast=head;
        ListNode* ans=new ListNode(0,head);
        ListNode* slow=ans;
        int i=0;
        while(fast&&i<n){
            fast=fast->next;
            i++;
        }
        while(fast){
            slow=slow->next;
            fast=fast->next;
        }
        slow->next=slow->next->next;
        return ans->next;
//具体解释看题解    剑指 Offer II 021. 删除链表的倒数第 n 个结点

        (5)链表中环的开始节点

        ListNode* fast=head;
        ListNode* slow=head;
        while(true){
            if(fast==NULL||fast->next==NULL)    return NULL;
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow)  break;
        }
        fast=head;
        while(fast!=slow){
            fast=fast->next;
            slow=slow->next;
        }
        return fast;
//具体看题解    剑指 Offer II 022. 链表中环的入口节点

 2.对撞指针

        (1)回文串问题

        (2)求n数和为目标值的问题

3.滑动窗口

        int slow=0;
        int fast=0;
        int mmax=INT_MAX;
        int sum=0;
        while(fast<nums.size()){            //注意两个while循环的判断条件
            sum+=nums[fast];
            while(sum>=target){            //注意两个while循环的判断条件
                mmax=min(mmax,fast-slow+1);
                sum-=nums[slow++];
            }
            fast++;
        }
        if(mmax==INT_MAX)   return 0;
        else    return mmax;
    }

LeetCode:     167:两数之和 II(双指针)(对撞指针)

LeetCode: 剑指 Offer II 007. 数组中和为 0 的三个数(双指针)(对撞指针)

LeetCode: 18. 四数之和(双指针)(对撞指针)

LeetCode: 剑指 Offer II 019. 最多删除一个字符得到回文(双指针)(对撞指针)

LeetCode: 剑指 Offer II 021. 删除链表的倒数第 n 个结点(双指针)(快慢指针)

LeetCode: 剑指 Offer II 022. 链表中环的入口节点(map)(双指针)(快慢指针)
 

LeetCode: 剑指 Offer II 023. 两个链表的第一个重合节点(双指针)(快慢指针)

LeetCode: 剑指 Offer II 026. 重排链表(双指针)(快慢指针)

LeetCode: 剑指 Offer 59 - I. 滑动窗口的最大值(双指针)(固定长度滑动窗口)

LeetCode: 剑指 Offer II 008. 和大于等于 target 的最短子数组(双指针)(不定长度滑动窗口)
 

举报

相关推荐

0 条评论