携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情
一、前言
每日算法坚持第三天,该专栏争取日日更新,加油
二、简介和示例
简介
LeetCode 19题, 删除链表的倒数第 N 个结点: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
链表数据结构
public class ListNode {
public int val;
public ListNode next;
public ListNode() {
}
public ListNode(int val) {
this.val = val;
}
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
示例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 <= 300 <= Node.val <= 1001 <= n <= sz
三、解题
思路分析
- 为了方便对头节点操作, 还是使用虚拟头节点
dummy来做 - 创建一个链表
slow表示当前节点 - 根据提示可知 n < 链表长度的
- 所以使用一个链表
fast去获取当前节点后第n个节点 - 搞一个链表
prev专门记录当前节点的上一个节点 - 循环终止条件是
fast链表的 next == null - 循环内操作
- prev 存储当前节点
- slow = slow.next
- fast = fast.next
- 循环结束之后, 上一节点是 prev, 下一节点是 slow.next
- 又因为我们的 dummy有一个虚拟头节点, 所以返回值为 dummy.next
这边我以为就结束了, 但是看大佬的代码, 还有一步 slow.next = null, 去释放掉了 slow.next
四、代码展示
public static ListNode removeNthFromEnd(ListNode head, int n) {
// 为了方便对头节点操作, 还是使用虚拟头节点 `dummy` 来做
ListNode dummy = new ListNode(-1);
dummy.next = head;
// 创建一个链表 `slow` 表示当前节点
ListNode slow = dummy;
// 使用一个链表 `fast` 去获取当前节点后第n个节点
ListNode fast = dummy;
// 根据提示可知 n < 链表长度的, 所以使用fast去判断slow节点是不是倒数第n个节点
while (n-- > 0) {
fast = fast.next;
}
// 记住 待删除节点slow 的上一节点
ListNode prev = null;
// 循环终止条件是 `fast` 链表的 next == null
while (fast != null) {
// prev 存储当前节点
prev = slow;
// slow和fast节点向下进一步
slow = slow.next;
fast = fast.next;
}
// 循环结束之后, 上一节点是 prev, 下一节点是 slow.next, 删除show节点
prev.next = slow.next;
// 下面是看大佬代码的收获
// 释放 待删除节点slow 的next指针, 这句删掉也能AC
slow.next = null;
return dummy.next;
}
五、提交代码
注: 本篇文章代码部分采用了代码随想录 大佬的代码在变量命名, fast链表的确认和最后一步的释放内存上比我自己的方式精简且清晰明了很多
本文内容到此结束了
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位大佬指出。
我是 宁轩 , 我们下次再见