LeeCode题目:链表中环的入口结点


题目描述

给定一个长度为n的链表,若其中包含环,请找出该链表的环的入口结点,否则返回空值。


示例

示例1
输入:head = [3,2,0,-4]
输出 :tail connects to node index 1(这个输出表示该链表中环的入口结点为索引为1的结点

算法思路

  • 首先,确认该链表中是否存在环:通过设置两个指针slow和fast,slow指针每次走一步,而fast指针每次走两步,当这两个指针相等时,则表明存在环(因为fast每次移动不能超过两步,所以存在环的话两个指针就会相遇)。
  • 注意相遇时的结点并非就是环的入口,要想确定环的入口,需要利用相遇时的结点信息:(1)假设头结点距离环的入口点有H步,入口点到第一次相遇点有D步,环的一圈为C步;(2)第一次相遇时假设fast指针相对于入口点转了n圈,那么第一次相遇时,slow指针运动了(H+D)步,fast指针运动了(H+nC+D);(3)因为fast是slow的两倍速度,则有2(H+D)=H+nC+D进一步得出:H = nC-D;(4)所以我们设置一个entry指针从头结点出发,而fast或slow指针以同样的速度从第一次相遇的位置出发,H步后,会在入口点相遇。

代码实现

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        slow = head
        fast = head
        entry = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
            # 利用相遇后的信息寻找入口点
                while entry != slow:
                    entry =entry.next
                    slow = slow.next
                return entry
        return None
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值