本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述:
二、思路分析:
思路一:考虑最直观的做法 —— 先遍历一遍链表 A,将值记录下来;再遍历链表 B 找到相交的节点。代码也很简单:
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
let nodeSet = new Set();
let pA = headA, pB = headB;
while (pA) {
nodeSet.add(pA);
pA = pA.next;
}
while (pB) {
if (nodeSet.has(pB)) return pB;
pB = pB.next;
}
return null;
};
这种做法时间和空间复杂度都是
O(N)。从执行结果看,在内存消耗上还有很大的提升空间。在链表的相关题目中,通常我们可以使用 (双)指针 进行性能优化。
看回本题的第一个例子:
- 我们使用两个指针,开始的时候,A、B 从各自的起点出发
- 由于链表 A 较短,A 会先遍历到尾节点,当 A 遍历到尾节点时,将其重定向到 B 的头部;同理 B
- 可以看到,在下一步,A、B 的起点一致;如果相交,一定会有相等的交点。
三、AC 代码:
参考评论区的优雅解法:
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
let pA = headA, pB = headB;
while (pA !== pB) {
pA = pA === null ? headB : pA.next;
pB = pB === null ? headA : pB.next;
}
return pB;
};
四、总结:
本文正在参与「掘金 4 月刷题打卡活动」, 点击查看 活动详情