用JavaScript刷leetcode第160题-相交链表

284 阅读2分钟

前言

将用两种解法解这道题:哈希表、双指针

  • 第一想法就是用用哈希表,哈希表存其中一个链表的所有节点,看另一个链表中的节点是否存在于哈希表内,存在则相交,反之不相交
  • 在看了leetcode题解,还可以用双指针来解这道题。空间复杂度更好,直接变成了常数阶O(1)。大致做法就是让两个指针从不同方向遍历两个链表的每个节点。

一、题目描述

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
具体的题目描述请看leetcode地址

二、解题

2.1 哈希表解法

2.1.1 思路

  • 把其中一个链表的所有节点都存入哈希表内
  • 访问另一个链表的所有节点,看哈希表内是否存在另一个链表的节点

2.1.2 代码

git代码地址

const getIntersectionNode = function(headA, headB) {
  // 任意一个链表为空,不可能相交
  if(headA === null || headB === null) return null
  // 哈希表
  const set = new Set()
  // 临时变量,遍历节点用
  let temp = headA
  // 遍历headA所在链表的所有节点,存入哈希表内
  while(temp !== null) {
    set.add(temp)
    temp = temp.next
  }
  // 遍历headB所在链表
  temp = headB
  while(temp !== null) {
    // 如果有相同节点说明相交
    if(set.has(temp)) return temp
    temp = temp.next
  }
  return temp
}

2.2 双指针解法

2.2.1 思路

  • 创建两个指针p、q
  • 这两个指针遍历两个链表的每个节点
  • 两个指针遍历出发点不一样:分别从不同的链表出发
  • 遍历时相遇则说明相交
  • 两个指针遍历结束还未相遇,则说明不相交。此时两个指针都指向null,故返回其中一个即可

2.2.2 代码

const getIntersectionNode = function(headA, headB) {
  // 任意一个链表为空,不可能相交
  if(headA === null || headB === null) return null

  // 创建双指针p、q,分别从不同链表头节点开始,遍历两个链表的所有节点
  let p = headA
  let q = headB
  // p、q不相等未遍历继续的条件,
  while(p !== q) {
    // 指针p依次遍历了以headA为起点的链表 、 以headB为起点的链表
    p = p === null ? headB : p.next 
    // 指针q依次遍历了以headB为起点的链表、 以headA为起点的链表
    q = q === null ? headA : q.next 
  }
  // 相交时p为某个节点,不相交时p为null
  return p
};