力扣题:142环形链表II

题目:

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

为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

说明:不允许修改给定的链表。

循环链表

python3代码解答:

# 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

        # 检查fast指针是否不为None和检查fast指针的下一个节点是否存在,即fast.next是否不为None
        while fast and fast.next:
            # slow每次移动一步,fast每次移动两步
            slow = slow.next
            fast = fast.next.next

            # 如果链表中存在环,由于fast移动的更快,它最终会从后面追上slow,并且相遇
            if slow == fast:
                # 一旦fast和slow进行相遇,就把slow设置为链表的头部
                # 接着slow和fast都以相同的速度移动(每次一步),他们再次相遇的点,就是环的起始节点
                slow = head
                while slow != fast:
                    slow = slow.next
                    fast = fast.next
                    # 当fast和slow再次相遇就是环的起始节点,此时可以返回任意一个指针指向的节点,就是起始节点
                return slow
        # 如果链表没有环,则fast会首先到达链表的表尾(fast或者fast.next会变成None)
        return None
        

上述代码解析:

       上述代码是用来在链表中检测环的存在,并且找到这个环的起始节点。使用“快慢指针”(Floyd的乌龟和兔子算法)的技术。核心思想是使用两个指针以不同的速度移动:一个快指针(每次移动两步)和一个慢指针(每次移动一步)。如果链表中存在环,那么快指针最终会从后面追上慢指针。具体解释如下:

  1. 起点设置:首先,将两个指针都放在链表的头部,这两个指针分别是slow(慢指针)和fast(快指针)。

  2. 开始追逐:在链表上移动这两个指针,slow每次移动一步,而fast每次移动两步。这一过程会持续进行,直到fast到达链表的末尾或者fast追上slow(即slow == fast)。

  3. 检测到环:如果链表中存在环,由于fast移动得更快,它最终会从后面追上slow,这时两者的位置相同。

  4. 找到环的起点:一旦slowfast相遇,就将slow重新设置到链表的头部,但这次两者都以相同的速度移动(每次一步)。他们再次相遇的点,就是环的起始节点。

  5. 返回环的起始节点:当slowfast再次相遇时,就在环的起始节点相遇。此时,返回任意一个指针指向的节点,这个节点就是环的起始点。

  6. 如果没有环:如果链表中没有环,那么fast会首先到达链表的末尾(fastfast.next会变成None)。这时,函数返回None,表示链表中没有环。

       该题的算法能够有效地在链表中检测环的存在,并找到环的入口点,好处是不需要额外的存储空间(比如使用一个集合来存储访问过的节点),所以它的空间复杂度为O(1),而时间复杂度保持为O(n),其中n是链表中的节点数。

注:其实不理解为什么在相遇之后,要把慢节点返回成头指针然后再以相同的速率去移动快慢指针,我们在自己计算的时候,就可以画类似这样的图,先判断在什么时候相遇,接着把慢指针指向头结点,最后在依次移动快慢指针,当他们再次相遇的时候,正好是下图所示的SB和fB点。(其中我以第一次移动的时候slow和fast写为123等。第二次移动写成AB等,表示的共同移动的步骤)

        本文的对于力扣142.环形链表II的python3解答,仅仅是个人学习资料记录,也十分高兴我的见解可以帮助其他的正在做这个题目的同学,基础较差,仅仅是个人见解,大神勿喷,欢迎交流,谢谢!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

又在熬

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

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

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

打赏作者

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

抵扣说明:

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

余额充值