快慢指针,双指针

一,快慢指针

快慢指针也被称为Hare&Tortoise算法,两个在数组(链表)中以不同速度移动的指针。

  • 应用场景:
  1. 处理链表或数组中的循环的问题,例如判断链表是否为环状
  2. 找链表中点或需要知道特定元素的位置
  • leetcode141环形链表
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast&&fast->next){
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow)
                return true;
        }
        return false;
    }
};
  • leetcode142,返回入环的第一个节点

preview

用快慢指针可以判断出链表是否有环,

假设在z 点 fast指针和slow 指针相遇。x-y 长度为a, y-z 长度为 b , z-y 长度为c。

则:slow 指针走了 a+b 的距离。 fast 指针走了 a + n(b + c)+ b 的距离。(可能不仅绕了一圈而是绕环走了n圈)

fast指针的速度是slow 指针速度的2倍。 所以a + b + n(b + c) = 2 (a + b), 简化得 a+b = n(b + c)。 因为我们想要求 a 的距离, 所以我们移动方程 得到 a = (n-1)b + n c 。

仔细观察上面的等式。 考虑它的含义, 即c 总比b 多一次, 这就意味着, 我们再放两个指针, first放在x ,second放在z ,这次保持速度一致, first 跑到y , second 也会跑到y。所以,当它们相遇,就是cycle的起点。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* slow=head;
        ListNode* fast=head;
        while(fast&&fast->next){
            slow=slow->next;
            fast=fast->next->next;
            if(fast==slow){
                ListNode *l1=head;
                ListNode *l2=fast;
                while(l1!=l2)
                {
                    l1=l1->next;
                    l2=l2->next;
                }
                return l1;
            }       
        }
        return 0;
    }
};
  • leetcode 234判断是否为回文链表

思路:先使用快慢指针找到中点,把前半部分逆转,再和后半部分链表逐个比较

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head || !head->next)
            return 1;
        ListNode *fast = head, *slow = head;
        ListNode *p, *pre = NULL;
        while(fast && fast->next){
            p = slow;
            slow = slow->next;    //快慢指针,寻找链表的中点
            fast = fast->next->next;

            p->next = pre;  //遍历慢指针,且翻转
            pre = p;
        }
        if(fast)  //奇数个节点时,fast为最后一个节点,需跳过中间节点;偶数个节点,fast为NULL
            slow = slow->next;
            
        while(p){       //前半部分和后半部分比较
            if(p->val != slow->val)
                return 0;
            p = p->next;
            slow = slow->next;
        }
        return 1;
    }
};

二,双指针

指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。这里指左右指针。

二分查找,两数之和,反转数组,滑动窗口

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值