160. 相交链表
给你两个单链表的头节点
headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null
。图示两个链表在节点
c1
开始相交:题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。
示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Intersected at '8' 解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。 在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 输出:Intersected at '2' 解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。 从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。 在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例 3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 输出:null 解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。 由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 这两个链表不相交,因此返回 null 。
提示:
listA
中节点数目为m
listB
中节点数目为n
0 <= m, n <= 3 * 10
4
1 <= Node.val <= 10
5
0 <= skipA <= m
0 <= skipB <= n
- 如果
listA
和listB
没有交点,intersectVal
为0
- 如果
listA
和listB
有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]
进阶:你能否设计一个时间复杂度
O(n)
、仅用 O(1)
内存的解决方案?通过次数349,570提交次数568,019
法1 双指针
思路
因为两链表如果有相交,那么从第一个焦点之后,一定不会再分开了。所以,先让快的节点走几步,使得当前两节点到末尾的节点距离一样,然后再一步一步的往后走,直到空或者两指针相同。
题解
# 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: count1 = 0 count2 = 0 cur1, cur2 = headA, headB while cur1: cur1 = cur1.next count1 += 1 while cur2: cur2 = cur2.next count2 += 1 first, second = (headA, headB) if count1 > count2 else (headB, headA) i = abs(count2-count1) while i > 0: first = first.next i -= 1 while first and second and first is not second: first = first.next second = second.next return first
法2 hash表存节点
思路
先用hash表将一链表存起来,然后再去遍历另外一个链表
题解
# 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: hashTable = set() cur = headA while cur: hashTable.add(cur) cur = cur.next cur = headB while cur: if cur in hashTable: return cur cur = cur.next return None
法 3
思路
按照 判断链表是否有环来做,两条链表
略
法4
走相同的长度,如果有交点,一定会在交点相遇;没有交点,则会在完整遍历完一遍之后都为None
# 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, b = headA, headB while a != b: a = a.next if a else headB b = b.next if b else headA return a