环形链表 力扣

题目描述

在这里插入图片描述

题目要求

判断一个单链表是不是环形链表,是就返回true 不是就返回false

思路

  1. 要搞清楚环形链表长啥样
  2. 环形链表有哪些特征

环形链表顾名思义就是在链表中有一个类似环形的结构, 它和普通单链表的区别就是 你用遍历普通单链表的法子遍历一个环形链表的话 会陷入死循环(因为环形链表没有一个节点指向NULL),而这恰好就是环形链表区别于普通链表的特征,我们以此为突破口

我们如何利用环形链表的这个特征呢?
我们要利用这个特征就是要看 在遍历这个链表的时候是不是陷入了循环里面。
怎么做呢?
答:快慢指针
为啥要用快慢指针呢?
答:
你遍历环形链表,当你的指针进入环后,它就出不来了,一直在环里转,
我们说过这是环形链表的特征。
我们把一个指针假设为一个人(小明)
我们在引入另一个指针(假设它叫小红),小红比小明跑的快。

当他们两个人同时从起点(头节点)出发后,小红跑在了前面(因为小红的速度快),小红就先进循环,小明就后进循环,但这个循环是死循环呀,他们永远也出不来,所以他们会在循环里一直跑,但小红的速度快呀,小红可能跑完一次循环后追上小明(意思就是小红要超小明一圈了,就和学校运动会跑3000米一样,跑的快的同学可能会追上最后的那名同学,超他一圈的距离),这个时候(就是小红要超过小明的时候)有小红这个指针等于小明这个指针
有这个特征就可以判断这是个环形链表了,因为如果是直的链表,由于小红的速度快,小红会永远跑在小明的前面,就不存在他们两相等的情况。
所以:
一个快指针fast 一个慢指针 slow
慢指针一次遍历一个节点,快指针可以一次遍历2个节点

我们可以写下这样的代码:

bool hasCycle(struct ListNode *head) 
{
    struct ListNode *fast = head;
    struct ListNode *slow = head;

while(fast && fast->next) //不能为空,如果为空的话下面就对空指针访问了
    {
        fast = fast->next->next;  //一次走两个节点
        slow = slow->next;        //一次走一个节点
         if(slow == fast)
        return true;
    }
   
    return false;
}

注意了哈
有朋友会问 为什么慢指针slow 要走1步,而快指针fast 要走2步
这个问题有点复杂
有规律得出,如果那个环里的节点是偶数个的话 那么只要fast比slow快就行,fast可以走3步,4步 都行
如果那个环里的节点数是奇数的话,那么fast如果不是走的2步就有可能直接跳过slow了(错过了,就比如fast还有一个节点就追上slow了,但由于fast一次走3个节点,他就直接跳过slow,指向了后面的节点了)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值