正题
删除链表的倒数第 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]
解析:
想要删除倒数第N个节点,思路很简单:
首先找到倒数第N个节点,设为 node ,node节点的上一个节点的 next 指针 指向 node 的next 节点 即可。链表的删除,实际上就是指针的指向变化。该节点可能依然存在,但是已经不在本链表任何节点的 next 指向。
所以可以分为几个步骤。
步骤一: 找到倒数第 N 个节点。
可以参考之前的文章: 三算法求得 链表中倒数第k个节点
这里我们采用双指针遍历法。
步骤二: 找到 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
};