返回
化繁为简:巧妙解决52. 两个链表的第一个公共节点
前端
2024-02-05 07:06:15
迎战LeetCode 52. 两个链表的第一个公共节点
题目
给出两个可能有环或无环的链表,找出它们的第一个公共节点。如果两个链表没有公共节点,返回空。
解法一:前后双指针(数节点)
1. 算法思路
前后双指针其实指的是一个指针先走 n 步,另一个指针再与前一个指针以相同的速度走。用到这个思路的还有 LeetCode 160. 相交链表。
将指针 A 和指针 B 都指向链表的头结点。然后,指针 A 先走 n 步,即让 A = A->next 走 n 次,同时让指针 B 走 m 步,即 B = B->next 走 m 次。
一旦指针 A 走完了 n 步,就让指针 B 开始走。之后,让指针 A 和指针 B 都走相同速度,即 A = A->next 和 B = B->next。如果指针 A 和指针 B 在链表中相遇,则说明链表 A 和链表 B 有公共节点,相遇的点就是公共节点。如果指针 A 和指针 B 走到了链表的末尾都没有相遇,则说明链表 A 和链表 B 没有公共节点。
2. 算法代码实现
def getIntersectionNode(headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
pA = headA
pB = headB
while pA != pB:
pA = headB if pA is None else pA.next
pB = headA if pB is None else pB.next
return pA
3. 算法复杂度
时间复杂度:O(n+m),其中 n 为链表 A 的长度,m 为链表 B 的长度。
空间复杂度:O(1),因为我们只需要使用常数个变量。
解法二:哈希表
1. 算法思路
使用哈希表存储链表 A 的所有节点。然后,遍历链表 B,如果当前节点在哈希表中,则返回该节点。否则,将当前节点添加到哈希表中,并继续遍历。
2. 算法代码实现
def getIntersectionNode(headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
seen = set()
while headA:
seen.add(headA)
headA = headA.next
while headB:
if headB in seen:
return headB
seen.add(headB)
headB = headB.next
return None
3. 算法复杂度
时间复杂度:O(n+m),其中 n 为链表 A 的长度,m 为链表 B 的长度。
空间复杂度:O(n),因为我们需要使用哈希表来存储链表 A 的所有节点。