142 环形链表 ||
题目142 环形链表
思路
主要考察两个点:一个判断是否有环,二是找到环的入口
一、判断链表是否有环
可以使用快慢指针法,分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
为什么fast 走两个节点,slow走一个节点,有环的话,一定会在环内相遇呢,而不是永远的错开呢?
因为fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合。
二:如果有环,如何找到这个环的入口
slow指针到相遇点时的路径:x+y+k(y+z)
fast指针到相遇点时的路径:x+y+n(y+z)
从而可以得到等式:2(x+y)=x+y+n(y+z),x=(n-1)(y+z)+z
证明:k=0,即一定在慢指针进入环后的第一圈就相遇到了,画个直线图就很明确了。另外,n≥1。
当n=1时,可以从等式得到x+z,
那么 n如果大于1是什么情况呢,就是fast指针在环形转n圈之后才遇到 slow指针。
其实这种情况和n为1的时候效果是一样的,一样可以通过这个方法找到 环形的入口节点,只不过,index1 指针在环里 多转了(n-1)圈,然后再遇到index2,相遇点依然是环形的入口节点。
代码
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def detectCycle(self, head: ListNode) -> ListNode: slow = head fast = head while fast != None and fast.next != None and fast.next.next != None: # 因为快指针移动两步,确保快指针指向不为空即可,若为空了,则无环无相遇点 slow = slow.next fast = fast.next.next if slow == fast: # 如果到了相遇的点 index_1 = head index_2 = slow while index_1 != index_2: # 找相遇点 index_1 = index_1.next index_2 = index_2.next return index_1 return None
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了