本文共 1634 字,大约阅读时间需要 5 分钟。
本系列文章为《剑指Offer》刷题笔记。
刷题平台:
快慢指针
基于以下两个结论:(1) 设置快慢指针,假如有环,他们最后一定相遇。
(2) 两个指针分别从链表头和相遇点继续出发,每次走一步,最后一定相遇与环入口。
证明结论1:设置快慢指针fast和low,fast每次走两步,low每次走一步。假如有环,两者一定会相遇(因为low一旦进环,可看作fast在后面追赶low的过程,每次两者都接近一步,最后一定能追上)。
证明结论2:
设: 链表头到环入口长度为 - - a 环入口到相遇点长度为 - - b 相遇点到环入口长度为 - - c如下图所示:
则:相遇时
快指针路程=a+(b+c)k+b ,k>=1 其中b+c为环的长度,k为绕环的圈数(k>=1,即最少一圈,不能是0圈,不然和慢指针走的一样长,矛盾)。 慢指针路程 = a+b 快指针走的路程是慢指针的两倍,所以:(a+b) * 2=a+(b+c)k+b化简可得:
a=(k-1)(b+c)+c 这个式子的意思是: 链表头到环入口的距离=相遇点到环入口的距离+(k-1)圈环长度。 其中k>=1,所以k-1>=0圈。所以两个指针分别从链表头和相遇点出发,最后一定相遇于环入口。
时间复杂度为O(n),空间复杂度为O(1)# -*- coding:utf-8 -*-# class ListNode:# def __init__(self, x):# self.val = x# self.next = Noneclass Solution: def EntryNodeOfLoop(self, pHead): # write code here if not pHead: return None pFast,pSlow = pHead,pHead while pFast: # pFast走的快,它先去探还有没有路 if pFast.next: pFast = pFast.next.next else: return None pSlow = pSlow.next if pFast == pSlow: # 此时pSlow停在遇见点 break newHead = pHead while newHead != pSlow: # pslow和newHead分别从遇见点和pHead出发,一步一步走,必然能够找到入口 newHead = newHead.next pSlow = pSlow.next return pSlow
https://blog.csdn.net/CSDN_SUSAN/article/details/103041082?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.not_use_machine_learn_pai&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.not_use_machine_learn_pai
https://blog.csdn.net/qq_36643449/article/details/106240794