持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
LeetCode 75 学习计划适用于想为技术面试做准备但不确定应该聚焦于哪些题目的用户。学习计划中的题目都是经过精心挑选的,Level 1和 Level 2 学习计划是为初级用户和中级用户准备的,题目覆盖了大多数中层公司面试时所必需的数据结构和算法,Level 3 学习计划则是为准备面试顶级公司的用户准备的。来源
第 4 天
链表的中间结点
难度:简单
题目
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
题解
众所周知,链表的优势在于插入容易,但是遍历较难。
我们不能通过直接通过拿下标的方式,拿到此题的解。
所以考虑遍历,将遍历到的元素依次放入数组 A 中。如果我们遍历到了 N 个元素,那么链表以及数组的长度也为 N,对应的中间节点即为 A[N/2]。
JavaScript 实现:
var middleNode = function(head) {
let A = [head];
while (A[A.length - 1].next != null)
A.push(A[A.length - 1].next);
return A[Math.trunc(A.length / 2)];
};
总结
看题解还有一种快慢指针的解法,也很绝:
var middleNode = function(head) {
slow = fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
};
用两个指针 slow 与 fast 一起遍历链表。slow 一次走一步,fast 一次走两步。那么当 fast 到达链表的末尾时,slow 必然位于中间。