OJ题目之环形链表2

环形链表Ⅱ

这一篇我们来讲解如何返回环形链表的入环节点环形链表Ⅱ
同样这里我们也需要两个快慢指针的存在
在这里插入图片描述
这里我们设头节点到环形入口的距离为L,环形的周长为C,入环口到快慢指针相遇的距离为N
(这里我们说到两个指针一定会相遇,具体请看环形链表,文章结尾有链接)
在这里插入图片描述

我们这里先给出一个结论:
从头结点到入环口的距离等于入环口到fast=slow这个节点的距离
为什么会有这样的结论呢?下面我们来证明一下:
slow指针走的距离:L+N;
fast指针走的距离:L+XC+N(这里慢指针只要进入环形,fast就一定会走一圈甚至更多,所以这里设置一个未知数X)
这里我们利用fast指针的速度是slow指针的二倍,所以我们得到一下等式
2(L+N)=L+X
C+N
化简一下得到
L=X*C - N
这里我们就需要结合数学思维来思考一下
最简单的情况就是我们这里X取1
得到L=C-N
在这里插入图片描述对吗,同学们这里可以清晰的看到fast=slow这个节点到入环口和头节点到入环口的距离是相等的

那么又有同学问了X如果不取1,我们这个结论还相等吗
答案是当然相等,我们这里在梳理一下思路
L=X*C - N这个式子我们是不是还可以将他改变一下形式
L=(X-1)*C+C-N
这个式子就更加清晰了,X不管再大,这里我们最后绕完圈圈,最后都需要加上一个(C-N)。

在这里插入图片描述

这里我们在定义一个head指针指向头节点和meet指针指向fast=slow的节点,L=(X-1)*C+C-N,这里我们结合这个式子看图,meet和head节点同时移动,这里我们可以看出head指针L距离走完meet不管在这个环形中绕了多少圈都会最终都是在入环口相遇。
接下来代码实现

  struct ListNode {    //题目中的链表结构
      int val;     
      struct ListNode *next;
  };
 
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* fast=head,*slow=head;  //这里我们依然定义快慢指针
    while(fast && fast->next) 
    {
        slow=slow->next;
        fast=fast->next->next;         //跟环形链表Ⅰ这个题目相同

        if(slow==fast)                 //到这里我们找到了两个指针在环形中相遇的节点
        {
            struct ListNode* meet = fast;
            while(meet!=head)     
            {              //定义meet和head指针同时移动
                meet=meet->next;
                head=head->next;
            }
            return meet;    //当两个指针相遇说明遇到入环口的节点
        }
    }
    return NULL;       //走到这里说明没有环形结构
}

题目到这里就写完了,如果有对链表不熟悉的同学可以看一下巨可爱熊写的关于链表的讲解
链表讲解
这里是环形链表Ⅰ的讲解环形链表Ⅰ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值