删除链表倒数第N个节点

610 阅读1分钟

正题

删除链表的倒数第 N 个结点

给你一个链表,删除链表的倒数第 n **个结点,并且返回链表的头结点。

示例1:

image.png

输入: head = [1,2,3,4,5], n = 2
输出: [1,2,3,5]

示例 2:

输入: head = [1], n = 1
输出: []

示例 3:

输入: head = [1,2], n = 1
输出: [1]

解析:

想要删除倒数第N个节点,思路很简单:

首先找到倒数第N个节点,设为 node ,node节点的上一个节点的 next 指针 指向 node 的next 节点 即可。链表的删除,实际上就是指针的指向变化。该节点可能依然存在,但是已经不在本链表任何节点的 next 指向。

所以可以分为几个步骤。

步骤一: 找到倒数第 N 个节点。

可以参考之前的文章: 三算法求得 链表中倒数第k个节点

这里我们采用双指针遍历法。

1.gif

步骤二: 找到 deleteNode 的前一个节点 pre

实际上可认为是 deleteNode = deleteNode.next 之前的 deleteNode 节点,也就是说在 更新 deleteNode 之前,可以认为他就是 pre 节点

步骤三: 连接 next 节点

步骤四: 边界问题

  • 如果只存在一个元素 那么返回空链表
  • 如果是删除链表第一个元素,那么就不存在 pre 节点, pre.next自然就不存在。那么可以直接返回 head.next
/**
 * 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}
 */
var removeNthFromEnd = function(head, n) {
    if (head.next === null) return new ListNode().next
    let p = head
    let deleteNode = head
    let index = 0
    let pre = null
    while(p) {
        if (index >= n) {
            pre = deleteNode
            deleteNode = deleteNode.next
        }
        index++
        p = p.next
    }
    pre === null ? head = head.next : pre.next = deleteNode.next
    return head
};