1:题目描述(力扣)
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
图示两个链表在节点 c1 开始相交:
2:解题思路
需要注意的是:交点不是数值相等,而是指针相等。
第一种解法:先分别求出两个链表的长度,再将两个链表尾部对齐,然后进行查找相同的节点(即相交点)
例如示例一:curA指向链表A的头结点,curB指向链表B的头结点:
我们求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,如图:
此时我们就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到交点。
否则循环退出返回空指针。
代码如下:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA, headB):
cur_a, res_a = headA, headA
cur_b, res_b = headB, headB
count_a = 0
count_b = 0
while cur_a != None:
count_a += 1 # 统计链表A的长度
cur_a = cur_a.next
while cur_b != None:
count_b += 1 # 统计链表B的长度
cur_b = cur_b.next
if count_a >= count_b: # 链表A的长度大于等于链表B的长度
for i in range(count_a-count_b):
# 将链表A与链表B尾部对齐,链表A的临时指针移动到和链表B头节点对齐的节点
res_a = res_a.next
while res_a != None and res_b != None:
if res_a == res_b: # 链表A的节点等于链表B的节点
return res_a # 返回其中一个一个节点
# 不等于,则链表A和链表B的临时指针同步向后移动一个节点
res_a = res_a.next
res_b = res_b.next
return None # 遍历所有节点后,没找到相交点
elif count_b > count_a:
for i in range(count_b-count_a):
res_b = res_b.next
while res_a != None and res_b != None:
if res_a == res_b:
return res_a
res_a = res_a.next
res_b = res_b.next
return None
第二种解法:根据快慢法则,走的快的一定会追上走得慢的。
在这道题里,有的链表短,他走完了就去走另一条链表,我们可以理解为走的快的指针。 那么,只要其中一个链表走完了,就去走另一条链表的路。如果有交点,他们最终一定会在同一个位置相遇。
代码如下:
class Solution:
def getIntersectionNode(self, headA, headB):
if headA is None or headB is None:
return None # 链表A或链表B为空,直接返回None
cur_a, cur_b = headA, headB # 定义两个临时指针,分别指向两个链表的头节点
while cur_a != cur_b:
# cur_a不为None,cur_a=cur_a.next,cur_a为None,cur_a=headB
# 链表A走完了,就切换到链表B
cur_a = cur_a.next if cur_a else headB
# cur_b不为None,cur_b=cur_b.next,cur_b为None,cur_b=headA
# 链表B走完了,就切换到链表A
cur_b = cur_b.next if cur_b else headA
return cur_a