快慢指针算法解环形链表问题

平衡二叉树好像有点难,我来写个简单的摸摸鱼(

环形链表问题

Leetcode上有这样一道题

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

只让判断是否有环,非常简单,根据之前的备忘录算法我很快写出了这串代码:

class Solution {
public:
    bool hasCycle(ListNode* head)
    {
        if(!head) return false;
        std::unordered_map<ListNode*,int> mem;
        while(head->next != nullptr)
        {
            if(mem.find(head) != mem.end()) return true;
            mem.insert(std::pair<ListNode*,int>(head,head->val));
            head = head->next;
        }
        return false;
    }
};

非常优雅,但…

xm3a34.png

xm3YNT.png

xm3t4U.png

可以说是惨不忍睹了,虽知哈希表以空间换时间,但全盘皆输,着实令人大跌眼镜。

快慢指针算法

又叫Floyd判圈法(弗洛伊德判圈法),简单地说就是在表的头部放置两个前进速度不同的指针,使他们同时出发,如果该表不是线性表,则前进速度快的指针会率先进入”循环圈“,慢指针紧随其后,使快指针追击慢指针。由于有速度差异,只要该”循环圈“存在,快指针在”循环圈“内运行若干周期后,总会追上慢指针,所以只要指针和慢指针相遇,我们就能认定该链表是环形链表。

基于以上理解,我们可以写出如下代码:

class Solution {
public:
    bool hasCycle(ListNode* head)
    {
        if(!head) return false;
        int count = 2;
        ListNode* slow = head;
        while(head->next)
        {
            if(count == 0)
            {
                count = 2;
                slow = slow->next;
            }
            else
            {
                --count;
                head = head->next;
            }
            if(slow == head) return true;
        }
        return false;
    }
};

效果立竿见影

xm3UCF.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值