[路飞]leetcode-160.相交链表

424 阅读2分钟

题目描述

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null

image.png

题目数据 保证 整个链式结构中不存在环。

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

原始题目

哈希Map思路

如果你之前做过链表判环或者看作者过上一篇链表判环的文章,可以尝试先不看此题目分析,试着自己推测一下Map实现,非常有助于巩固你的代码语感哦~

题目分析

  1. 创建一个Map用来存放数据(所有hash思路均如此处理)
  2. 判断两个链表是否相交,我们可以以一条链表为基准,遍历循环将此链表所有节点放入已经创建好了的Map中。
  3. 再遍历第二条链表,如果两链表相交,则第一个被找到的存在于Map中的数据,则为相交的节点值
  4. Map中不存在重复节点,return null
  5. 边界值处理:两个链表存在一个为空,则不想交,两个链表只有一个节点且值不一致,同样不相交

代码实现

var getIntersectionNode = function (headA, headB) {
    if (!headA || !headB) return null;
    const mapper = new Map();
    let nodeA = headA;
    let nodeB = headB;
    while (nodeA) {
        mapper.set(nodeA, nodeA);
        nodeA = nodeA.next;
    }

    while (nodeB) {
        if (mapper.get(nodeB)) {
            return nodeB;
        }
        nodeB = nodeB.next;
    }

    return null;
};

双指针方法

思路分析

1、两个链表各有两个头结点,各自从头开始,证明结构如下图

image.png

上图可以看出,无论链表是否相交, a + b + c === b + c + a,二者不同在于如果相交则相交节点相等,如果不交,则循环完毕依然没有相等节点。

代码实现

var getIntersectionNode = function (headA, headB) {
    if (!headA || !headB) return null;
    let nodeA = headA;
    let nodeB = headB;

    while (nodeA !== nodeB) {
        nodeA = nodeA === null ? headB : nodeA.next;
        nodeB = nodeB === null ? headA : nodeB.next;
    }

    return nodeA;
};