链表中等1 种解法
#19删除链表的倒数第 N 个结点
使用相距 n 个节点的快慢指针,一趟扫描定位并删除倒数第 n 个节点。
#链表#双指针
解题主线
01
虚拟头节点把删除头节点统一成删除 slow.next。
02
fast 先移动 n 步;随后 fast 到达尾节点时,slow 恰好位于待删节点的前驱。
解法 1:快慢指针
在虚拟头节点上建立长度为 n 的间隔,再同步移动两个指针并绕过 slow.next。
时间复杂度
O(L),L 为链表长度
空间复杂度
O(1)
java
public class Solution {
static final class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public ListNode removeNthFromEnd(ListNode head, int n) {
if (n <= 0) throw new IllegalArgumentException("n must be positive");
ListNode dummy = new ListNode(0, head);
ListNode fast = dummy;
ListNode slow = dummy;
for (int i = 0; i < n; i++) {
fast = fast.next;
if (fast == null) throw new IllegalArgumentException("n exceeds list length");
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}在虚拟头节点上建立长度为 n 的间隔,再同步移动两个指针并绕过 slow.next。
- 两个旧文件实现相同,合并为一个解法并补上非法 n 的保护。
边界与易错点
- 原实现默认 n 合法,n 大于链长时会空指针;展示代码显式校验 n 与链长。
- 循环终止条件应为 fast.next != null,否则 slow 会停在待删节点而不是其前驱。
整理来源
由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。
Q019_removeEndNthListNode.javaQ019_removeNthFromEnd.java