这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战
前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
给你一个链表,删除链表的倒数第 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]
链接:leetcode-cn.com/problems/re…
题解
-
快慢指针. 首先, 我们可以利用快慢指针来找出倒数第 n 个节点: 快慢指针一开始都指向 head 节点, 先让快指针走 n 步, 然后快慢指针一起走. 当快指针为空时, 慢指针此时指向的就是倒数第 n 个元素.
但是, 这道题是让我们把倒数第 n 个元素从链表中删除, 所以我们要找的是倒数第 n + 1 个元素, 通过第 n+1 个元素把第 n 个元素从链表中删除. 那么, 如果我们初始时让慢指针指向 head, 快指针指向 head.next, 然后再按照上面的方法向后遍历, 就能找到第 n+1 个元素. 但是, 这个方法存在缺陷, 当链表只有一个元素, 比如 [1] 的时候, 快指针为空, 我们就需要特殊处理这种情况.
所以, 一种更通用的方法是构造一个假的头部, 假头部的 next 指针指向 head. 我们用慢指针指向假头部, 快指针指向 head, 那么就不用额外考虑边界条件, 而是一种通用的解法.
具体代码如下, 时间复杂度 O(n)
/**
* 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) {
// 假头部
const dummy = new ListNode(0, head)
let slow = dummy
let fast = head
while (n--) fast = fast.next
while (fast) {
fast = fast.next
slow = slow.next
}
let nth = slow.next
if (nth) {
nth_next = nth.next
slow.next = nth_next
}
return dummy.next
};
- 栈. 栈是一种先进后出的数据结构, 所以利用栈我们能找到倒数第 n + 1 个元素. 具体做法是将所有节点入栈, 然后在出栈, 出栈的时候计数即可. 具体解法不再写出.