剑指 Offer 52. 两个链表的第一个公共节点
题目:
输入两个链表,找出它们的第一个公共节点。
方法一:暴力循环:
直接用指针循环会超时,所以用list存了每个指针,再循环list,用时非常久。
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA == None or headB == None:
return None
pointer_a = headA
pointer_b = headB
list_a = []
list_b = []
while pointer_a != None:
list_a.append(pointer_a)
pointer_a = pointer_a.next
while pointer_b != None:
list_b.append(pointer_b)
pointer_b = pointer_b.next
for i in list_a:
for j in list_b:
if i == j:
return i
方法二:双指针法
Mark来自大佬的解法:大佬力扣页
使用两个指针分别从两个链表头开始,向下遍历至空节点后转从另一条链表头开始继续遍历,直至两指针汇合到同一节点。
具体逻辑: 利用链表在相交节点后半部分完全相同的前提,设后半部分长度为L1 ,第一条链表前半部分长度L2 ,第二条链表前半部分长度L3 ,两个指针的第一次相遇时,第一个指针会走完L2 + L1 + L3 步,第二个指针会走完 L3 + L1 + L2 步,他们的步数相同一定会落到那个相交节点上。
如果不相交他们都会走L2 + L1 + L3 + L1 步之后,落到None上。
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
pointer_a = headA
pointer_b = headB
while pointer_a != pointer_b:
pointer_a = pointer_a.next if pointer_a else headB
pointer_b = pointer_b.next if pointer_b else headA
return pointer_a
方法三:长度差值
两条链表长度不等,只需要让长的链表先走长度差值步,再同时走,遇到的第一个相同节点即是公共节点。
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
pointer_a = headA
pointer_b = headB
length_a = 0
length_b = 0
#计算长度
while pointer_a != None:
length_a += 1
pointer_a = pointer_a.next
while pointer_b != None:
length_b += 1
pointer_b = pointer_b.next
#让长的链表先走
if length_a >= length_b:
length_pass = length_a - length_b
pointer_a = headA
for i in range(length_pass):
pointer_a = pointer_a.next
#另一个指针拨到头节点
pointer_b = headB
else:
length_pass = length_b - length_a
pointer_b = headB
for i in range(length_pass):
pointer_b = pointer_b.next
#另一个指针拨到头节点
pointer_a = headA
#同时开始
while pointer_a != pointer_b:
if pointer_a == None or pointer_b == None:
return None
pointer_a = pointer_a.next
pointer_b = pointer_b.next
return pointer_a