# Definition for singly-linked list. classListNode: def__init__(self, x): self.val = x self.next = None defcreateLink_rearinsert_cycle(lista,pos): head = ListNode(-1) rear = head for i in range(len(lista)): new_node=ListNode(lista[i]) if i==pos: pos_node = new_node rear.next=new_node rear=new_node if pos!=-1: rear.next=pos_node
return head.next
classSolution: defdetectCycle(self, head: ListNode) -> ListNode: seen = set() while head: if head in seen: return head seen.add(head) head = head.next returnNone
if __name__=="__main__": head = [3,2,0,-4] pos = 1 new_a=createLink_rearinsert_cycle(head,pos) a1 = Solution() p=a1.detectCycle(new_a) print(p)
<__main__.ListNode object at 0x000001CED72B6A48>
复杂度分析
时间复杂度:O(N),其中 N 为链表中节点的数目。我们恰好需要访问链表中的每一个节点。
空间复杂度:O(N),其中 N 为链表中节点的数目。我们需要将链表中的每个节点都保存在哈希表当中。
方法二:快慢指针
思路与算法
我们使用两个指针,fast和slow。它们起始都位于链表的头部。随后,slow指针每次向后移动一个位置,而 fast指针向后移动两个位置。如果链表中存在环,则 fast 指针最终将再次与 slow 指针在环中相遇。
如下图所示,设链表中环外部分的长度为 a。slow 指针进入环后,又走了 b的距离与 fast 相遇。此时,fast指针已经走完了环的n圈,因此它走过的总距离为 a+n(b+c)+b=a+(n+1)b+nc。
# Definition for singly-linked list. classListNode: def__init__(self, x): self.val = x self.next = None defcreateLink_rearinsert_cycle(lista,pos): head = ListNode(-1) rear = head for i in range(len(lista)): new_node=ListNode(lista[i]) if i==pos: pos_node = new_node rear.next=new_node rear=new_node if pos!=-1: rear.next=pos_node
return head.next classSolution: defdetectCycle(self, head: ListNode) -> ListNode: ifnot head ornot head.next: returnNone slow = head fast = head.next
while slow != fast: ifnot fast ornot fast.next: returnNone slow = slow.next fast = fast.next.next ptr=head while ptr!=slow.next: ptr=ptr.next slow=slow.next return ptr if __name__=="__main__": head = [3,2,0,-4] pos = 1 new_a=createLink_rearinsert_cycle(head,pos) a1 = Solution() p=a1.detectCycle(new_a) print(p)