每日一题——链表中环的入口

每日一题

链表中环的入口节点

题目链接

在这里插入图片描述

思路(双指针法)

  • 第一步:第一步当然是判断该链表是否存在环。由昨天的题目判断链表是否有环,可以很简单的进行判断
  • 第二步:即找到环的入口节点。
    • 我们可以在第一步中可以得到快慢指针相遇的节点位置,可以设相遇节点到头节点的距离为X,环入口节点到相遇节点的距离为Y(从左到右),相遇节点到环入口节点的距离为Z(从右到左),如此图中,X = 2, Y = 2, Z = 2
    • 如图:在这里插入图片描述
  • 由分析可得:当快慢指针相遇时,慢指针slow一共走了X + m(Y + Z) + Y个节点,快指针fast一共走了X + n(Y + Z) + Y个节点,我们预定快指针fast每次比慢指针slow多走一个节点,则X + n(Y + Z) + Y = 2(X + m(Y + Z) + Y),即X + Y = (n - 2m)(Y + Z),即X = (n - 2m - 1)(Y + Z) + Z。
  • 我们可以再定义连个指针index1,index2,令index1指向链表头,index2指向快慢指针相遇的节点,并每次让index1,index2每次一起走一个节点,由X = (n - 2m - 1)(Y + Z) + Z可知,index1走到环入口节点所走过的节点数恰好等于index2走到环入口节点所走过的节点数加上整数倍环的节点数,即当index1与index2相遇的点即为环的入口节点。

实现代码

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead ListNode类 
 * @return ListNode类
 */
struct ListNode * Judge_Loop(struct ListNode *pHead) 	//判断链表是否有环的函数,如果没有,则返回NULL,如果有,则返回相遇的节点
{
    if(!pHead)
        return NULL;
    struct ListNode*fast,*slow;
    fast = slow = pHead;
    while(slow && fast)
    {
        slow = slow->next;
        if(!fast->next)
            return NULL;
        fast = fast->next->next;
        if(fast == slow)
            return fast;
    }
    return NULL;
}
struct ListNode* EntryNodeOfLoop(struct ListNode* pHead ) {
    if(!Judge_Loop(pHead))		//如果链表没有环,则直接返回NULL
        return NULL;
    struct ListNode* index1 = pHead;		//令index1指向表头
    struct ListNode* index2 = Judge_Loop(pHead);		//令index2指向相遇节点
    while(1)
    {
        if(index1 == index2)	//当index1和index2再次相遇时,相遇位置即为环的入口
            return index1;
        index1 = index1->next;		//index1,index2每次下滑一个位置
        index2 = index2->next;
    }
}
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Forward♞

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

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

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

打赏作者

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

抵扣说明:

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

余额充值