LeetCode 160. 相交链表 | 刷题打卡

182 阅读1分钟

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一、题目描述:

题目选自 LeetCode 160

image.png

二、思路分析:

思路一:考虑最直观的做法 —— 先遍历一遍链表 A,将值记录下来;再遍历链表 B 找到相交的节点。代码也很简单:

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function (headA, headB) {
    let nodeSet = new Set();
    let pA = headA, pB = headB;
    while (pA) {
        nodeSet.add(pA);
        pA = pA.next;
    }
    while (pB) {
        if (nodeSet.has(pB)) return pB;
        pB = pB.next;
    }
    return null;
};

image.png 这种做法时间和空间复杂度都是 O(N)。从执行结果看,在内存消耗上还有很大的提升空间。在链表的相关题目中,通常我们可以使用 (双)指针 进行性能优化。

看回本题的第一个例子:

  • 我们使用两个指针,开始的时候,A、B 从各自的起点出发 image.png
  • 由于链表 A 较短,A 会先遍历到尾节点,当 A 遍历到尾节点时,将其重定向到 B 的头部;同理 B image.png
  • 可以看到,在下一步,A、B 的起点一致;如果相交,一定会有相等的交点。 image.png

三、AC 代码:

参考评论区的优雅解法:

/**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */
var getIntersectionNode = function (headA, headB) {
    let pA = headA, pB = headB;
    while (pA !== pB) {
        pA = pA === null ? headB : pA.next;
        pB = pB === null ? headA : pB.next;
    }
    return pB;
};

image.png

四、总结:

本文正在参与「掘金 4 月刷题打卡活动」, 点击查看 活动详情