题目描述
给你一个链表,删除链表的倒数第
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]
提示:
- 链表中结点的数目为
sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
进阶:你能尝试使用一趟扫描实现吗?
解题思路
要删除链表中的倒数第 n 个节点,进阶要求使用一趟扫描来实现。可以使用双指针法(快慢指针)来完成这个任务。
-
初始化双指针:使用两个指针
fast
和slow
,都指向链表的头节点。 -
移动快指针:将
fast
指针先向前移动n
步,这样fast
和slow
之间就会有n
的差距。 -
同时移动快慢指针:然后同时移动
fast
和slow
指针,直到fast
到达链表的末尾;此时,slow
指针正好停在要删除的节点的前一个节点上。 -
删除节点:修改
slow.next
指针,跳过需要删除的节点。 -
返回链表头:如果删除的是头节点,需要特别处理,直接返回
head.next
。
复杂度分析
- 时间复杂度O(sz): 其中
sz
是链表的长度,只需一次遍历。 - 空间复杂度O(1): 只使用了常数个额外的指针。
代码实现
package org.zyf.javabasic.letcode.hot100.list;
import org.zyf.javabasic.letcode.list.base.ListNode;
/**
* @program: zyfboot-javabasic
* @description: 删除链表的倒数第 N 个结点(中等)
* @author: zhangyanfeng
* @create: 2024-08-22 10:01
**/
public class RemoveNthFromEndSolution {
public ListNode removeNthFromEnd(ListNode head, int n) {
// 创建一个哨兵节点,以应对删除头节点的情况
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode fast = dummy;
ListNode slow = dummy;
// 快指针先移动 n 步
for (int i = 0; i < n; i++) {
fast = fast.next;
}
// 快慢指针一起移动,直到快指针到达链表末尾
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
// 删除慢指针所指节点的下一个节点
slow.next = slow.next.next;
// 返回链表头节点
return dummy.next;
}
public static void main(String[] args) {
RemoveNthFromEndSolution solution = new RemoveNthFromEndSolution();
// 测试用例 1
ListNode l1 = new ListNode(1);
l1.next = new ListNode(2);
l1.next.next = new ListNode(3);
l1.next.next.next = new ListNode(4);
l1.next.next.next.next = new ListNode(5);
ListNode result1 = solution.removeNthFromEnd(l1, 2);
printList(result1); // 输出应该为 [1, 2, 3, 5]
// 测试用例 2
ListNode l2 = new ListNode(1);
ListNode result2 = solution.removeNthFromEnd(l2, 1);
printList(result2); // 输出应该为 []
// 测试用例 3
ListNode l3 = new ListNode(1);
l3.next = new ListNode(2);
ListNode result3 = solution.removeNthFromEnd(l3, 1);
printList(result3); // 输出应该为 [1]
}
// 打印链表的辅助函数
private static void printList(ListNode node) {
while (node != null) {
System.out.print(node.val + " ");
node = node.next;
}
System.out.println();
}
}
具体可参考:https://zyfcodes.blog.csdn.net/article/details/141401712