用JavaScript刷leetcode第19题-删除链表的倒数第N个节点

457 阅读2分钟

前言

这道题leetcode 官方给出了三种解答。分别是:

  1. 两次遍历:第一次遍历计算链表长度,第二次遍历找出待删除节点的前一个节点。没看答案前我就是用这个方法解题的
  2. 栈:利用后进先出。遍历把每个节点存到栈中,出栈N+1次,找到待删除节点的前一个节点
  3. 双指针解法:让一个指针先走k步,然后两个指针一起走,当先走的指针走完链表停止,此时后走的指针即指向待删除节点的前一个节点

在这三种解法,第三种无论是空间复杂度还是时间复杂度都是最优的。故我这里就只介绍第三种解法-双指针解法

一、题目描述

详细描述请看leetcode题目描述
描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例:

image.png

二、解题

本次将用双指针的方法来解题

2.1 思路

  • 首先要明确删除某个节点,要找到待删除节点的前一个节点
  • 两个指针pre、cur分别指向虚头、头节点。
  • cur走n步
  • 然后pre、cur再一起走,直到cur指向null
  • 此时pre指向待删除节点的前一个节点

2.2 代码

git代码地址

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
 
const removeNthFromEnd = function(head, n) {
  // 虚拟头节点
  const dummy = new ListNode(-1, head)
  // pre指针最后指向被删节点的前一个节点, cur指针遍历链表用
  let pre = dummy, cur = head
  
  // cur 先走n步
  while(n--) {
    cur = cur.next
  }

  // pre、cur同时走,直到cur走到了null, 此时pre走到了待删除节点的前一个节点
  while(cur) {
    cur = cur.next
    pre = pre.next
  }

  // 删除节点
  pre.next = pre.next.next

  return dummy.next
}