題目:
Given the heads of two singly linked-lists headA and headB, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return null.
The test cases are generated such that there are no cycles anywhere in the entire linked structure.
Note that the linked lists must retain their original structure after the function returns.
給定兩個linked list,假如兩者在某一點交會變同一條,回傳該點
若都無交會,回傳None
本來我想到的是做記號或是reverse,讓我們比較好找到交會點
但題目有特別說linked list要維持原樣,因此這些方法都不可行
最後我想到的方案是將兩者對齊
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
lenA=0
lenB=0
A=headA
B=headB
while A:
lenA=lenA+1
A=A.next
while B:
lenB=lenB+1
B=B.next
i=abs(lenA-lenB)
if lenB>lenA:
for j in range(i):
headB=headB.next
else:
for j in range(i):
headA=headA.next
while headA and headB:
if headA==headB:
return headA
headA=headA.next
headB=headB.next
return None
因為兩個linked list從交會點到尾端的距離是一樣的
所以我們讓兩個linked list在尾端對齊
讓短的linked list從頭,長的linked list從短linked list頭對齊到的位置出發
這樣兩個指標就會同時到交會點或尾端
所以我們量了兩個linked list的長度
透過它們將長linked list的起始點移到對其到短linked list頭的位置
開始遍歷就能知道交會點是否存在及其位置了
最後執行時間164ms(faster than 92.83%)
但上面那個辦法需要先量測長度,稍微慢了些
我在討論區看到了一個無需測量長度的解法,十分簡潔
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
a=headA
b=headB
while a!=b:
if a==None:
a=headB
else:
a=a.next
if b==None:
b=headA
else:
b=b.next
return a
兩個linked list都從頭開始跑,跑到底就換從另一個linked list的頭開始跑
這樣兩個指標移動最長都會跑到len(linked list1)+len(linked list2)的距離
如此過程中就會達到對齊的效果
因為當長linked list的指標跑完從短linked list的頭開始時
跑完短linked list的指標已經在長linked list上跑完兩者長度差的長度了
接著就看它們遇到相同的點即為交會點
最後執行時間155ms(faster than 98.27%)
那我們下題見