leetcode刷题记录-19. 删除链表的倒数第 N 个结点

127 阅读2分钟

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

题解

快慢指针

在做这道题之前,我们需要来先了解一下链表的数据结构是什么样的:

image.png

结合上图以及题目给的注释:

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */

我们得出链表的一个数据结构是对象嵌套式的,对象中的val就是当前结点的值,next就是下一个结点。

那么题目要我们删除倒数第n个结点,然后返回头结点。

这里我们用快慢指针的思路来解题,下图将讲解一下快慢指针的思路:

image.png

对于上面这样的五个结点的链表,假如我们要删除倒数第二个结点。

结合上面说的,每一个结点是上一个结点的 netx ,那么我们要删除倒数第二个结点,就需要知道倒数第三个结点是什么。

那么要怎么去知道倒数第三个结点呢,我们可以定义两个指针,其中指针 fast 比 指针 cur 多前进了 n+1 步:

image.png

那么在这之后,如果两个指针一起向后移动,当 fase 移动到null的时候,指针 cur 指向的就会是需要删除的结点的 前一个 结点:

image.png

如此我们就可以删除这时候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;
};

image.png