当前位置: 首页 > news >正文

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

题目描述

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

示例 1:

img

输入: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 <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

进阶:你能尝试使用一趟扫描实现吗?

解法一

思路:

采用递归的方法就可以反向搜索,首先进行递归遍历得到需要删除节点的前驱节点。之后根据节点位置进行删除,需要删除的节点是头节点需要特殊考虑。

代码:

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public int num=0;public ListNode target;public boolean flag=false;public void search(ListNode head, int n) {if(head == null) return ;else{search(head.next,n);}num++;if(num==n+1){target=head;flag=true;}}public ListNode removeNthFromEnd(ListNode head, int n) {search(head,n);if(flag==false){ListNode head1=head.next;return head1;}else{target.next=target.next.next;return head;}}
}

解法二

思路:

在第一种方法上的进阶考虑。

在对链表进行操作时,一种常用的技巧是添加一个哑节点(dummy node),它的 next 指针指向链表的头节点。这样一来,我们就不需要对头节点进行特殊的判断了。

例如,在本题中,如果我们要删除节点 y,我们需要知道节点 y 的前驱节点 x,并将 x 的指针指向 y 的后继节点。但由于头节点不存在前驱节点,因此我们需要在删除头节点时进行特殊判断。但如果我们添加了哑节点,那么头节点的前驱节点就是哑节点本身,此时我们就只需要考虑通用的情况即可。

1

代码:

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public  int num=0;public  ListNode target;public  boolean flag=false;public  void search(ListNode head, int n) {if(head == null) return ;else{search(head.next,n);}num++;if(num==n+1){target=head;flag=true;}}public ListNode removeNthFromEnd(ListNode head, int n) {//哑节点ListNode dummy = new ListNode(0, head);search(dummy,n);target.next=target.next.next;return dummy.next;}
}

解法三

思路:

来自官方题解。

我们也可以在遍历链表的同时将所有节点依次入栈。根据栈「先进后出」的原则,我们弹出栈的第 n 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点。这样一来,删除操作就变得十分方便了。

代码:

class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0, head);Deque<ListNode> stack = new LinkedList<ListNode>();ListNode cur = dummy;while (cur != null) {stack.push(cur);cur = cur.next;}for (int i = 0; i < n; ++i) {stack.pop();}ListNode prev = stack.peek();prev.next = prev.next.next;ListNode ans = dummy.next;return ans;}
}

解法四

思路:

来自官方题解。

我们也可以在不预处理出链表的长度,以及使用常数空间的前提下解决本题。

由于我们需要找到倒数第 n 个节点,因此我们可以使用两个指针 first 和 second 同时对链表进行遍历,并且 first 比 second 超前 n 个节点。当 first 遍历到链表的末尾时,second 就恰好处于倒数第 n 个节点。

具体地,初始时 first 和 second 均指向头节点。我们首先使用 first 对链表进行遍历,遍历的次数为 n。此时,first 和 second 之间间隔了 n−1 个节点,即 first 比 second 超前了 n 个节点。

在这之后,我们同时使用 first 和 second 对链表进行遍历。当 first 遍历到链表的末尾(即 first 为空指针)时,second 恰好指向倒数第 n 个节点。

根据方法一和方法二,如果我们能够得到的是倒数第 n 个节点的前驱节点而不是倒数第 n 个节点的话,删除操作会更加方便。因此我们可以考虑在初始时将 second 指向哑节点,其余的操作步骤不变。这样一来,当 first 遍历到链表的末尾时,second 的下一个节点就是我们需要删除的节点。

2

代码:

class Solution {public ListNode removeNthFromEnd(ListNode head, int n) {ListNode dummy = new ListNode(0, head);ListNode first = head;ListNode second = dummy;for (int i = 0; i < n; ++i) {first = first.next;}while (first != null) {first = first.next;second = second.next;}second.next = second.next.next;ListNode ans = dummy.next;return ans;}
}
http://www.hskmm.com/?act=detail&tid=36140

相关文章:

  • NOI 八
  • Day1标签的关系与vs的注释
  • 软件工程学习日志2025.10.21
  • [PaperReading] DeepSeek-OCR: Contexts Optical Compression
  • Win10安装WindowsCamera相机
  • 简易的本地部署OI-Wiki方法 for CCSP
  • Say 题选记 (10.19 - 10.25)
  • 宝塔面板
  • React Native 启动流程 (Android版)
  • 以TrustedInstaller/System用户运行软件
  • 10月21号
  • 机器学习基础 -- 线性回归模型
  • 泰勒展开
  • MySQL 创建和授权用户
  • 因果机器学习算法新进展解析
  • 软件工程作业三
  • CF2127 Atto Round 1 (Codeforces Round 1041, Div. 1 + Div. 2) 游记(VP)
  • 一键生成爆款文章,并自动发布!
  • 机器学习到深度学习发展历程
  • Java数据类型
  • [CF 516 E] Drazil and His Happy Friends
  • NVIDIA Triton服务器漏洞危机:攻击者可远程执行代码,AI模型最高权限告急
  • 2025-10-21
  • 个人骗分导论
  • Java三大特性
  • 高级程序设计第二次作业
  • 10月21日日记
  • home-assistant.-Adding integrations
  • Windows系统内存占用过高,且任务管理器找不到对应进程
  • NOIP 二十五