Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
前言
今天的第二题难度为中等,题目涉及到链表的知识,在js中链表是用对象去描述的,如果不是很清楚链表结构的,那就需要先去理解清除,这是做链表题的基础。
每日一题
第二题的题目是 19. 删除链表的倒数第 N 个结点,难度为中等
- 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
- 链表中结点的数目为 sz
- 1 <= sz <= 30
- 0 <= Node.val <= 100
- 1 <= n <= sz
题解
快慢指针
在做这道题之前,我们需要来先了解一下链表的数据结构是什么样的:
结合上图以及题目给的注释:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
我们得出链表的一个数据结构是对象嵌套式的,对象中的val就是当前结点的值,next就是下一个结点。
那么题目要我们删除倒数第n个结点,然后返回头结点。
这里我们用快慢指针的思路来解题,下图将讲解一下快慢指针的思路:
对于上面这样的五个结点的链表,假如我们要删除倒数第二个结点。
结合上面说的,每一个结点是上一个结点的 netx ,那么我们要删除倒数第二个结点,就需要知道倒数第三个结点是什么。
那么要怎么去知道倒数第三个结点呢,我们可以定义两个指针,其中指针 fast 比 指针 cur 多前进了 n+1 步:
那么在这之后,如果两个指针一起向后移动,当 fase 移动到null的时候,指针 cur 指向的就会是需要删除的结点的 前一个 结点:
如此我们就可以删除这时候cur的下一个结点,然后返回头结点就可以了。
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function (head, n) {
if (n == 0) {
return head;
}
let cur = head;
let fast = head;
let pre = head;
for (let i = 0; i < n; i++) {
fast = fast.next;
}
if (!fast) {
head = head.next;
return head;
}
while (fast) {
pre = cur;
cur = cur.next;
fast = fast.next;
}
pre.next = cur.next;
return head;
};