力扣刷题TOP101:5.BM6 判断链表中是否有环

目录:

目的

思路

复杂度

记忆秘诀

python代码

目的

{3,2,0,-4}, 1 这表示有环即为True。-1代表无环False,其它的数字代表有环。

 


思路

这个任务是判断一个链表是否包含环(循环路径),避免在操作链表时出现无限循环的问题。可以简单理解为龟兔赛跑(Floyd 判圈算法),兔子快,乌龟慢,但路是圈圈(有环)兔子必定追上。路有终点(无环),兔子先到头不等乌龟了。


准备阶段:

  • 参赛选手:

    • 乌龟(慢指针slow): 每次只走一步,慢悠悠的。slow = head
    • 兔子(快指针fast): 每次跳两步,飞快地往前冲。fast = head.next
    • 为什么这样安排?
      • 让兔子先跳一步,确保开始时不会立刻相遇(head != head.next)。
      • 保证比赛开始时有足够的间隔,能正确判断链表中是否有环。
  • 特例处理:

    • 如果这条路上只有一个点(链表为空head == None或只有一个节点head.next == None),直接告诉你没环,环的形成至少需要两个节点,因此直接返回 False

比赛规则:

只要兔子还没跑出链表(fast != Nonefast.next != None),比赛继续。

  • 为什么检查两个条件?
    • fast 如果 fast == None,说明兔子已经跑到了链表的尽头,没有环。
    • fast.next 是兔子跳两步时需要访问的下一个节点。fast.next == None,说明兔子已经没有“下一步”可以跳,也意味着链表没有环。

比赛开始:

  • 乌龟稳步前进 走一步,代表慢速slow = slow.next。
  • 兔子飞速跳跃 跳两步,代表快速移动fast = fast.next.next。
  • 相遇时刻 如果乌龟和兔子相遇,比赛结束(slow == fast)。说明链表有环(True),退出循环。
  • 为什么一定会相遇?
    • 如果链表是闭环,兔子因为步伐更快,最终会在环内兜圈,追上乌龟。

比赛结束:

如果比赛结束了(循环退出),乌龟和兔子没有相遇,说明兔子跑到了头,链表没有环(False)。


复杂度

  • 时间复杂度:O(n)

    • 每次兔子和乌龟各走一段路,总路程不会超过链表长度的两倍。
  • 空间复杂度:O(1)

    • 只用了两只小动物(两个指针变量),省吃俭用,不多花内存。

记忆秘诀

  1. 乌龟走一步,兔子跳两步。
  2. 链表有环,相遇无误。
  3. 链表无环,兔子先停步。

python代码

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

#
# 
# @param head ListNode类 
# @return bool布尔型
#
class Solution:
    def hasCycle(self , head: ListNode) -> bool:
        if not head or not head.next:
            # 比赛没法开始,直接判无环
            return False  # 如果链表为空或者只有一个节点,则无环

        slow = head  # 慢指针 # 乌龟
        fast = head.next  # 快指针 # 兔子

        # 快慢指针开始移动
        while fast and fast.next: # 兔子还没跑出赛道
            slow = slow.next  # 慢指针走一步 # 乌龟走一步
            fast = fast.next.next  # 快指针走两步 # 兔子跳两步
            
            # 乌龟和兔子相遇,有环
            if slow == fast:
                return True  # 快慢指针相遇,说明有环
            

        return False  # 如果没有相遇,则无环 # 兔子跑出赛道,无环

* 欢迎大家探讨新思路,能够更好的理解和记忆

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

乱七八糟2333

随缘打赏,一分也是爱!

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

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

打赏作者

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

抵扣说明:

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

余额充值