「集合」leetcode 160.相交链表(简单)

238 阅读3分钟

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

一、了解题目

附上原题链接:160. 相交链表

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

图示两个链表在节点 c1 开始相交:

img

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

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

示例 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 个节点。

二、题解分析

判断两个链表是否相交,那么我们可以使用哈希集合存储链表节点具体步骤如下:

  • 首先遍历链表 headA,并将链表 headA 中的每个节点加入哈希集合中;
  • 然后遍历链表 headB ,对于遍历到的每个节点,判断该节点是否在哈希集合中
  • 如果当前节点不在哈希集合中,则继续遍历下一个节点;
  • 如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都在两个链表的相交部分,因此在链表 headB 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点,返回该节点;
  • 如果链表 headB 中的所有节点都不在哈希集合中,则两个链表不相交,返回 null

三、代码实现

依据上面的题解,我们将用 js 来实现这道题。具体实现代码如下:

/**
 * @description leetcode 160.相交链表
 *//**
 * @param {ListNode} headA
 * @param {ListNode} headB
 * @return {ListNode}
 */var getIntersectionNode = function (headA, headB) {
  // 1.定义一个空集合,存放链表A中的节点
  const visited = new Set();
  // 2.定义temp指针,指向headA
  let temp = headA;
  // 3.不断循环temp指针,并将temp指针指向链表的下一个节点,直到temp指针为空时再结束循环
  while (temp !== null) {
      visited.add(temp);
      temp = temp.next;
  }
  // 4.将temp指针指向链表B
  temp = headB;
  // 5.不断循环链表B
  while (temp !== null) {
    // 5.1 判断链表B的节点是否有与链表A相同的,如果有,则返回
      if (visited.has(temp)) {
          return temp;
      }
      temp = temp.next;
  }
  // 6.如果找不到相同的节点,则返回null
  return null;
};

四、复杂度分析

最后,我们来做下上述题目的复杂度分析。具体如下:

时间复杂度: O(m+n) ,其中 mn 是分别是链表 headAheadB 的长度。需要遍历两个链表各一次

空间复杂度: O(m) ,其中 m 是链表 headA 的长度。需要使用哈希集合存储链表 headA 中的全部节点。


思路来源:相交链表

看到这里,可以再尝试着设计一个时间复杂度为 O(n) 、 空间复杂度为 O(1) 的解决方案。如果有思路,评论区留下你的答案呀~

以上就是关于相交链表的题解,不知道对小伙伴们是否有帮助呢?

我们下期见👋👋👋