142.LeetCode刷题之环形链表2

1. 题目描述:

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题思路:

1,判断是否有环,利用快慢指针,fast一次走两步,slow一次走一步,如果能够相遇则有环,且当相遇的时候 slow 一定是在环内没走完一圈,因为假设slow入环的时候fast正在环内距离入环口m的位置,这样当fast到达入环口3的时候走的路程是(m+n)对应的slow走的路程就一定是 (m+n)/2 而m一定是小于n的,所以当fast再次走到第三个入环口的时候,slow刚刚的那一圈还没有走完,所以一定是slow进环的第一圈相遇

2,找到相遇点后如何找到入环口

  • 假设fast在环内走了n圈后在y点相遇
  • 可以得到公式
  • 2(x+y) = x + n(y+z) +y
  • 化简得 x = (n-1)(y+z) + z
  • 可以知道,当n = 1的时候 x = z
  • 因为(y+z)就是环的结点个数 A ,进而可以理解为 x = A + z 此时就可以推断出:
  • 不论n等于几,当一个指针从相遇结点,一个指针从开始结点同时出发,当他们相遇的时候就是入口结点,因为 x = z
  • 参考思路出处
3. 解题代码:
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        //总体思想是快慢指针
        ListNode *fast = head,*slow = head;
        while(fast != nullptr && fast->next != nullptr){
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow){
                //相遇   x = (n-1)(y+z)+z
                //这就可以得出,当n = 1 的时候,x = z
                //进而可以推导出,一个结点从相遇点出发,一个指针从头节点出发,那么他们会刚好到入环点相遇
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while(index1 != index2){
                    index1 = index1 -> next;
                    index2 = index2 -> next;
                }
                return index1;
            }
        }
        return nullptr;
    }
};
4. tips:

如何判断链表有环:使用快慢指针,一个一次走两步,一个一次走一步,如果能相遇,则说明是有环的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

强大的RGG

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

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

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

打赏作者

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

抵扣说明:

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

余额充值