环形链表找进入环的节点(C语言实现)


原题是这个:(以下都是通过C来实现的并且是单向链表)
在这里插入图片描述
首先得需要知道是否有环形链表,判断:

一.环形链表判断:

首先,我们要知道如果不是环行链表,直线链表的尾节点肯定指向NULL,所以只要证明尾节点没有指向NULL即可;
我们可以把环形链表想象成这个图:
在这里插入图片描述
一个简单的数学问题:
一个男孩和一个女孩沿着一个圆圈走,男孩每次走两步,女孩每次走一步,那无论在圆的任何地方男孩总会追上女孩,因为圈的周长是固定的,而男孩与女孩的距离会一步一步缩减直到0。
故得出其相遇的节点即可证明是一个圆(毕竟同一起跑线跑,如果是直线男孩会越来越远),放到这题即可证明是一个环形链表。
这样我们把男孩设成指针quick,女孩为slow,放置在同一起跑线
在这里插入图片描述

quick走两步,slow走一步,假设其meet处会相遇,这样既求出相遇点和证明其是环形链表。代码如下:

struct ListNode 
{
	int val;
    struct ListNode *next;
 };
struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode* quick = head;
    struct ListNode* slow = head;
    while(quick && quick->next)
    {
        quick = quick->next->next;
        slow = slow->next;
        if(quick == slow)
        {
           return quick;
        }
    }

二.找到进入环形的节点:

再来一个简单的数学问题:
在这里插入图片描述
设起点到入环节点距离为:L,入环节点到quick与slow相遇点meet距离为X,圆的周长为C。
由此我们可以得到这样的关系:
quick走的路程为:L+X+nC (n >= 1) n为在圈里面转的圈数。
slow走的路程为: L+X
而quick走的路程是slow走的两倍,
故得出:L+X+nC = 2(L+X)
化简为: L+X=nC
     L=nC-X
通过这个式子我们得出:quick(slow)从起点出发,slow(quick)从相遇点(meet)出发,会在环形节点相遇。
不懂再解释一下:
假设:quick对应的L,slow对应的nC-X。quick已经走了L步,slow走了n圈还差X,就是nC-X,那就是相遇点:(如图)
在这里插入图片描述
meet-x不就是节点吗,不就是nC。
原理知道了我们来看题并实现代码:
在这里插入图片描述

struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode* quick = head;
    struct ListNode* slow = head;
    struct ListNode* meet = NULL;
    while(quick && quick->next)
    {
        quick = quick->next->next;
        slow = slow->next;
        if(quick == slow)
        {
            meet = quick;
            break;
        }
    }
    if(meet == NULL)
    {
        return NULL;
    }
    else
    {
        quick = head;
        while(quick != slow)
        {
            quick = quick->next;
            slow = slow->next;
        }
        return quick;
    }
}

如果有错误请大佬指点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅碎时光807

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值