环形链表2
思路
环形链表如图
要做本题目不仅要判断链表是否有环,还要判断环入口位置
首先怎么判断链表有环呢?
我们可以定义一个快指针fast,每次走两步,定义一个慢指针slow,每次走一步
如果有slow == fast,则代表链表有环(fast相当于每次是一个节点一个节点的靠近slow的)
相遇之后怎么判断环的入口位置呢?
在相遇位置定义一个指针position1,在头部定义一个指针position2,这两个指针position1==position2的时候,即为环入口的节点位置。
其证明方法在这里就不过多叙述,可以看卡尔老师的文字讲解证明过程,
文字版证明过程--代码随想录 ,
或者看视频版教程把环形链表讲清楚! 如何判断环形链表?如何找到环形链表的入口? LeetCode:142.环形链表II_哔哩哔哩_bilibili
另外看到另一个解题思路更加简单易懂:代码随想录算法训练营Day4 | | 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 , 面试题 02.07. 链表相交
方法一: 双指针法
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
fast = head
slow = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
index = head
while slow != index:
slow = slow.next
index = index.next
return slow
return None
方法二:集合
class Solution1:
def detectCycle(self, head: ListNode) -> ListNode:
common = set()
cur = head
while cur:
if cur in common:
return cur
common.add(cur)
return None
心得收获
重新看题目讲解时,发现一刷的时候根本没有仔细看,今天又看了一遍,在写代码时候发现还是没有思路,然后思考了下自己的问题,因为有现成的思路解题,所以自己就比较依赖老师的思路,但是看完之后自己并没有回头去整理自己的解题思路。在这里要批评一下自己,在后续的刷题中一定要复盘自己的思路,多一些思考和见解。所以在这里感谢训练营让坚持写博客,并不仅仅是打卡自己看过了,而是通过写博客再次复盘自己的解题思路和一些思考见解。
在用集合解题过程中,自己以为每个节点的值相等,然后节点就是相等的,这种思维完全是错的,所以自己模拟了一下建了一个循环链表,可以帮助小伙伴理解。
所以使用集合的时候,把节点放入集合,用来判断有没有出现过逻辑完全可以行的通,而且代码更加简单明了