data =newSet() // 存放A链表的所有节点的地址whileA不为空{ 哈希表中添加A链表当前节点A指针向后移动}whileB不为空{if 如果哈希表中含有B链表当前节点returnBB指针向后移动}returnnull// 两条链表没有相交点
代码支持: JS
JS Code:
let data =newSet();while (A!==null) {data.add(A);A=A.next;}while (B!==null) {if (data.has(B)) returnB;B=B.next;}returnnull;
复杂度分析
时间复杂度:$O(N)$
空间复杂度:$O(N)$
解法二:双指针
例如使用 a, b 两个指针分别指向 A, B 这两条链表, 两个指针相同的速度向后移动,
当 a 到达链表的尾部时,重定位到链表 B 的头结点
当 b 到达链表的尾部时,重定位到链表 A 的头结点。
a, b 指针相遇的点为相交的起始节点,否则没有相交点
(图 5)
为什么 a, b 指针相遇的点一定是相交的起始节点? 我们证明一下:
将两条链表按相交的起始节点继续截断,链表 1 为: A + C,链表 2 为: B + C
当 a 指针将链表 1 遍历完后,重定位到链表 B 的头结点,然后继续遍历直至相交点(a 指针遍历的距离为 A + C + B)
同理 b 指针遍历的距离为 B + C + A
伪代码
a = headAb = headBwhile a,b指针不相等时 {if a指针为空时 a指针重定位到链表 B的头结点else a指针向后移动一位if b指针为空时 b指针重定位到链表 A的头结点else b指针向后移动一位}return a
代码支持: JS, Python, Go, PHP
JS Code:
vargetIntersectionNode=function (headA, headB) {let a = headA, b = headB;while (a != b) { a = a ===null? headB :a.next; b = b ===null? headA :b.next; }return a;};
Python Code:
classSolution:defgetIntersectionNode(self,headA: ListNode,headB: ListNode) -> ListNode: a, b = headA, headBwhile a != b: a = a.next if a else headB b = b.next if b else headAreturn a
Go Code:
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */funcgetIntersectionNode(headA, headB *ListNode) *ListNode {// a=A(a单独部分)+C(a相交部分); b=B(b单独部分)+C(b相交部分)// a+b=b+a=A+C+B+C=B+C+A+C a := headA b := headBfor a != b {if a ==nil { a = headB } else { a = a.Next }if b ==nil { b = headA } else { b = b.Next } }return a}