欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

leetcode142环形链表Ⅱ

程序员文章站 2022-06-17 19:10:58
...

题目

leetcode142环形链表Ⅱ

思路1

利用hash表,每当走到一个节点,判断该节点是否已经存在hash表中,如果存在,则该节点就是要求的节点,否则将其加入hash表,直到走到尾节点。

python中的set的底层实现就是hash表(与list的顺序存储不同,set效率要高于list,尤其是大数据查找下),所以可以直接利用set来进行操作。

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        s = set([])
        while head:
            if head in s:
                return head
            else:
                s.add(head)
            head = head.next

时间复杂度空间复杂度都是O(n)。

思路2

Floyd算法

Floyd判圈算法,也称龟兔赛跑算法,可用于判断链表、迭代函数、有限状态机是否有环。如果有,找出环的起点和大小。时间复杂度O(n),空间复杂度O(1)。

第一步:慢指针走1步,快指针走2步,如果不能相遇,说明没有环,否则找到快慢指针相遇的点。
第二步:慢指针指向头节点,快指针指向第一步中的相遇节点,两个指针都走一步,则它们再相遇的点就是环的入口!!!

证明

leetcode142环形链表Ⅱ
①在第一步中,快指针走的步数(F+a+b+a)是慢指针走的步数(F+a)的两倍(a+b+a是因为快指针一定是饶了环的一圈才遇到慢指针)。
所以有:

F+a+b+a = 2(F+a)
F+2a+b = 2F+2a
F = b
②所以第二步两个指针都走1步,则一定是在环的入口相遇。

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if not head: return
        s, q = head, head
        flag = 0  # flag用来判断是否有环
        while q.next and q.next.next:  # 第1步
            s = s.next
            q = q.next.next
            if s == q:
                flag = 1
                break
        if not flag: return  # 无环返回None
        s = head  # 第2步
        while s != q:
            s = s.next
            q = q.next
        return s
相关标签: leetcode