今天学习如何在环形链表中寻找环的起点节点,学习使用快慢节点遍历环形列表,并且理解其中存在的数学规律,这是我认为在计算机算法中比较难得一点,当然今天最令人印象深刻的当属这张图了:

在相遇时,fast走过的节点一定是slow节点的2倍,从而有公式(x + y) * 2 = x + y + n (y + z)
因为我们需要求的是x,所以化简后又为x = (n - 1) (y + z) + z
可以从图中看出从头结点发出一个指针index1,让他每次只走一步,再从相遇节点发出一个指针index2,也让他每次只走一步,他们一定会在环形入口相遇,因为从公式中可以看出,index1走过x步以后,index2也相当于走了z步+额外围着环转了(n-1)圈,index2走了z步后即到了环起点,再无论转多少圈仍然回到起点,所以可以通过这个方法找到环的入口。
今天编写代码需注意的点:
1.while循环的条件是fast!=None and fast.next!=None,不是判断fast.next和fast.next.next
2.因为指针不为空即可,所以不需要加!=None的判定,直接while fast and fast.next即可
3.Optional[ListNode]意思是既可能是ListNode类型,也可能是空
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast=head
slow=head
while fast!=None and fast.next!=None:
fast=fast.next.next
slow=slow.next
if fast==slow:
index1=fast
index2=head
while index1!=index2:
index1=index1.next
index2=index2.next
return index2
return None
1006

被折叠的 条评论
为什么被折叠?



