实现思路
方法1 双指针
1 考虑到A和B的链表长度可能不同,所以如果依次移动pa和pb,那么就永远无法【同时】指向相交对象
2 假设A的链表长度m = a + c; B的链表长度 n= b + c
- 其中 c是 A和B的相交节点的长度
- 当 a !== b时,一开始依次移动 pa和pb,肯定无法指向 同一个相交对象t
- 这时候可以在pa遍历完A链表后,继续从B链表的头节点开始,依次向下移动
- 同理,pb遍历完B链表后,继续从A链表的头节点开始,依次向下移动
- 就这样每次都依次移动pa和pb,那么在pa移动 a+c+b次后,此时pb必然移动的是 b+c+a次
- 此时 pa的值必然等于pb,此时也是相加链表的头节点,从而命中了pa === pb
方法2 Set记录法
1 就是直观的 遍历A链表并记录,然后再B链表里遍历查询有无相同节点
参考文档
代码实现
方法1: 双指针 时间复杂度: O(m+n) 空间复杂度: O(1)
function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null {
let pa = headA, pb = headB
while (pa || pb) {
if (pa === pb) return pa
pa = pa ? pa.next : headB
pb = pb ? pb.next : headA
}
return pa
};
方法2: Set记录法 时间复杂度: O(m+n) 空间复杂度: O(m)
function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null {
let seen = new Set();
for (let pa = headA; pa; pa = pa.next) {
if (pa) seen.add(pa);
}
for (let pb = headB; pb; pb = pb.next) {
if (seen.has(pb)) return pb;
}
return null;
};