找出链表中的入环点

原题出处:https://leetcode.cn/problems/c32eOV/description/

PS:题目描述:
给定一个链表,返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环,则返回 null
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos -1 ,则在该链表中没有环。注意, pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。

题目描述过于抽象,简单一点就是找出该链表的入环点。

说这道题目之前,想先聊一聊小学问题追击问题,假设有两个人A、B在一个环形跑道上跑步,他们的跑步速度每时每刻都是不受外部影响的,A的速度是3m/s,B的速度是4m/s,试问:他们会在什么时候相遇?这是小学的奥数题,也称为追击问题。

这道题的思路和追击问题一个思路,跟找一个链表的中点思路一致,使用两个快慢指针,快指针一次走2步,慢指针一次走1步,当fast指针进入环的起点的时候,假设此刻fast指针走了L个单位距离,那么此时该点距离slow指针就还有L/2个单位距离,然后让slow再继续走L/2个单位距离,此刻,fast与slow就都在环内部了,而此刻就由fast来追slow,设他们的距离为N个单位距离,因为他们没走一次,距离差值就会减1,那么最终肯定会相遇。这道题有2个隐藏坑点,一个是fast在环内是否是只走了一圈,第二个是为什么要用快慢指针,一个走一步,一个走两步,现在 先卖个关子提出问题,让大家思考一下,在最后我会跟大家娓娓道来。

上步骤图:

设:进入环点之前的距离为L,slow走的距离为X,环的距离为C

可看出slow走的距离为L+X,然而此刻,fast走了 多少距离呢?,是slow的两倍,即2(L+X)

得出公式: .slow* 2 = fast

再想一下,fast实际是走了哪些节点呢?首=首先有这段距离,然后进入环内,那么环走了几圈呢?假设这个环的长度非常大,多大呢?足足可以容纳L/2个单位距离,为什么是L/2呢?假设不能容纳该大小单位,那么在slow进入环内,不是fast柚走了一圈C ,也就是说,在环内,fast将会出现一些特殊情况, 例如走了多圈

那么现在可得出以下公式: .

2*(L + X)=L+ NC+ X

L+X=NC

L= NC- X

L= (N- 1)*C+ N- X

最后得出两个新链表的长度:

L + X (指向head)

N - X(指向相遇节点)

然后按照这个思路来写代码

struct ListNode *detectCycle(struct ListNode *head) {
    if(!head)//如果给的空链表,就直接返回
        return head;
    struct ListNode *slow = head, *fast = head;//定义两个快慢指针,这种方法也可以适用于找链表中点
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;//让fast走的步数,始终为slow的两倍
        if(slow == fast)//当他们相同了,就代表此刻相遇了,此时他们的距离为N
        {//然后就开始找相遇点
            struct ListNode* MeetNode = slow;

            struct ListNode* NewHead = head;
            while(MeetNode != NewHead)开始遍历,当相等了,那么就找到入环起始点了
            {
                MeetNode = MeetNode->next;
                NewHead = NewHead->next;
            }
            return MeetNode;
        }
    }
    return NULL;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值