1 题目描述
2 解题思路
2.1 哈希表
遍历listA,把每个节点(以及后继节点)放入一个list中。遍历完A之后遍历B,如果B的某个节点(以及后继节点)在这个list中,那么我们就找到了相交的部分。
这里只给出思路,因为用不同的语言用时是不一样的。python的话会超时。
# 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) -> ListNode:
lst=[]
while(headA!=None):
lst.append(headA)
headA=headA.next
while(headB!=None):
if(headB in lst):
return headB
headB=headB.next
return None
2.2 双指针
2.2.1 主要思路
主要思路如下:
创建两个指针pA 和pB,初始时分别指向两个链表的头节点headA 和headB,然后将两个指针依次遍历两个链表的每个节点。具体做法如下:
->每步操作需要同时更新指针pA 和 pB;
->如果指针pA 不为空,则将指针pA 移到下一个节点;如果指针pB 不为空,则将指针pB 移到下一个节点。
->如果指针pA 为空,则将指针pA 移到链表 headB 的头节点;如果指针 pB 为空,则将指针 pB 移到链表headA 的头节点。
->当指针pA 和pB 指向同一个节点或者都为空时,返回它们指向的节点或者 null。
2.2.2 图示
2.2.3 证明
考虑两种情况,第一种情况是两个链表相交,第二种情况是两个链表不相交。
情况一:两个链表相交
链表headA 和headB 的长度分别是m 和n。假设链表headA 的不相交部分有 a 个节点,链表 headB 的不相交部分有 b 个节点,两个链表相交的部分有 c 个节点,则有 a+c=m,b+c=n。
如果 a=b,则两个指针会同时到达两个链表相交的节点,此时返回相交的节点;
如果 a ≠b,则指针pA 会遍历完链表headA,指针pB 会遍历完链表headB,两个指针不会同时到达链表的尾节点。然后指针pA 遍历完headA后,移到链表 headB 的头节点;指针pB 遍历完headB后,移到链表headA 的头节点,然后两个指针继续移动,在指针pA 移动了a+c+b 次、指针 pB 移动了 b+c+a 次之后,两个指针会同时到达两个链表相交的节点,该节点也是两个指针第一次同时指向的节点,此时返回相交的节点。
情况二:两个链表不相交
链表headA 和headB 的长度分别是 m 和 n。考虑当 m=n 和 m≠n时,两个指针分别会如何移动:
如果m=n,则两个指针会同时到达两个链表的尾节点,然后同时变成空值null,此时返回 null;
如果 m≠n,则由于两个链表没有公共节点,两个指针也不会同时到达两个链表的尾节点,因此两个指针都会遍历完两个链表,在指针pA 移动了 m+n次、指针 pB 移动了n+m 次之后,两个指针会同时变成空值 null,此时返回 null。
2.2.4 代码
# 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) -> ListNode:
pa=headA
pb=headB
while(pa!=pb):
if(pa!=None):
pa=pa.next
else:
pa=headB
if(pb!=None):
pb=pb.next
else:
pb=headA
if(pa==None):
return None
else:
return pa