删除链表的倒数第 N 个结点——实战技巧让你轻松应对
2023-03-15 01:16:42
征服 LeetCode 第 19 题:巧用指针,删除链表倒数第 N 个结点
简介
对于程序员而言,算法题是必不可少的训练场,它能检验你的编程能力并促进你的成长。今天,我们就来挑战 LeetCode 第 19 题:删除链表的倒数第 N 个结点。这是一道中等难度的题目,非常适合初学者练习。
题目
给你一个链表,删除链表的倒数第 N 个结点,并返回链表的头结点。
解题思路
解题方法有多种,但这里介绍两种最常见的策略:
双指针法
双指针法是一个巧妙的技巧,它使用两个指针来遍历链表。我们设置一个指针指向链表的头部,另一个指针指向链表的尾部。这两个指针同时向前移动,直到尾指针到达链表的倒数第 N 个结点。此时,头指针恰好指向链表的倒数第 N+1 个结点,我们可以安全地删除它。
代码实现
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);
ListNode first = dummy;
ListNode second = dummy;
for (int i = 0; i < n; i++) {
second = second.next;
}
while (second.next != null) {
first = first.next;
second = second.next;
}
first.next = first.next.next;
return dummy.next;
}
快慢指针法
快慢指针法与双指针法类似,但它使用了一个快指针和一个慢指针。快指针每次移动两个结点,而慢指针每次移动一个结点。当快指针到达链表末尾时,慢指针恰好指向链表的倒数第 N 个结点。
代码实现
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode fast = head;
ListNode slow = head;
for (int i = 0; i < n; i++) {
fast = fast.next;
}
if (fast == null) {
return head.next;
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
}
结论
掌握了解决 LeetCode 第 19 题的方法后,你就能轻松应对类似的链表问题。算法题是提升编程技能的必经之路,每天坚持练习,相信你的编码思维会突飞猛进。
常见问题解答
1. 什么是倒数第 N 个结点?
倒数第 N 个结点是指从链表尾部开始数起的第 N 个结点。
2. 双指针法和快慢指针法有什么区别?
双指针法使用两个指针同时向前移动,而快慢指针法使用一个指针每次移动两个结点,另一个指针每次移动一个结点。
3. 为什么在双指针法中需要一个虚拟头结点?
虚拟头结点可以简化代码逻辑,避免特殊情况的处理。
4. 快慢指针法中,快指针如何跳过 N 个结点?
快指针每次移动两个结点,因此它可以在 n 步内跳过 n 个结点。
5. 如何处理链表长度小于 N 的情况?
如果链表长度小于 N,则需要特殊处理,如返回 null 或抛出异常。