JS算法-链表相交

82 阅读2分钟

题目

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

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。

题解

第一种

首先我们在函数中先初始化变量 lenA, lenB, a, b 分别为 0, 0, headA, headB,然后通过 while 循环遍历链表 A 和 B,计算它们的长度 lenA 和 lenB,并记录最后一个节点 a 和 b, 如果 a !== b,说明它们没有交点,直接返回 null,如果 lenA > lenB,说明链表 A 比链表 B 长,交换它们的位置,使得 lenA <= lenB,接下来初始化变量 count = lenB - lenA,表示链表 B 需要向后移动的步数,在通过 while 循环将链表 B 向后移动 count 步,同时遍历链表 A 和 B,直到找到第一个相同的节点,即为它们的交点,最后返回交点或 null

var getIntersectionNode = function (headA, headB) {
  let lenA = 0;
  let lenB = 0;
  let a = headA;
  let b = headB;
  while (a.next) {
    lenA++;
    a = a.next;
  }
  while (b.next) {
    lenB++;
    b = b.next;
  }
  if (a !== b) return null;
  if (lenA > lenB) {
    [headA, headB] = [headB, headA];
    [lenA, lenB] = [lenB, lenA];
  }
  let count = lenB - lenA;
  while (count--) {
    headB = headB.next;
  }
  while (headB && headA) {
    if (headB === headA) return headA;
    headB = headB.next;
    headA = headA.next;
  }
  return null;
};

第二种

首先定义两个指针p1和p2,分别指向两个链表的头节点,然后在while循环中,判断p1和p2是否相等。如果相等,说明已经找到了两个链表的交点,直接返回p1即可,如果p1或p2为null,说明已经到达了链表的末尾,需要将它们重新指向另一个链表的头节点,继续遍历。如果p1为null,就将它指向headB;如果p2为null,就将它指向headA,最后,如果两个链表有交点,while循环结束后p1就指向了交点。如果两个链表没有交点,while循环结束后p1和p2都为null,直接返回其中一个即可

var getIntersectionNode = function (headA, headB) {
  let p1 = headA, p2 = headB;
  while (p1 != p2) {
    if (p1 == null) {
      p1 = headB
    } else {
      p1 = p1.next
    }
    if (p2 == null) {
      p2 = headA
    } else {
      p2 = p2.next
    }
  }
  return p1
};

坚持努力,无惧未来!