题目
你两个单链表的头节点 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 };