基础知识要求:
Java:方法、while循环、for循环
Python: 方法、while循环、for循环
题目:
给你一个链表,删除链表的倒数第 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
思路解析:
- 创建哑节点(Dummy Node):
- 为了方便处理头节点的删除情况,我们通常在链表头部添加一个哑节点。哑节点本身不存储任何数据,只是它的
next
指针指向链表的头节点。这样,无论我们要删除的是头节点还是其他节点,我们都可以统一处理。
- 为了方便处理头节点的删除情况,我们通常在链表头部添加一个哑节点。哑节点本身不存储任何数据,只是它的
- 初始化快慢指针:
- 我们有两个指针,一个快指针
fast
和一个慢指针slow
,都初始化为哑节点。
- 我们有两个指针,一个快指针
- 快指针先走n步:
- 我们让快指针先向前走n步,这样快指针和慢指针之间就拉开了n个节点的距离。
- 快慢指针同时移动:
- 接着,我们让快慢指针同时向前移动。当快指针到达链表末尾(即
fast.next
为None
)时,慢指针slow
就指向了倒数第n+1个节点(因为我们要删除的是倒数第n个节点)。
- 接着,我们让快慢指针同时向前移动。当快指针到达链表末尾(即
- 删除倒数第n个节点:
- 此时,我们只需要将慢指针的
next
指针指向下下个节点(即slow.next.next
),就可以删除倒数第n个节点了。
- 此时,我们只需要将慢指针的
- 返回结果:
- 因为我们使用了哑节点,所以最终返回的是哑节点的
next
指针,也就是修改后的链表的头节点。
- 因为我们使用了哑节点,所以最终返回的是哑节点的
快慢指针示例解释:
以输入head = [1,2,3,4,5], n = 2
为例:
- 初始状态:
- 哑节点:
0 -> 1 -> 2 -> 3 -> 4 -> 5
fast
和slow
都指向哑节点。
- 哑节点:
- 快指针先走2步:
fast
现在指向2
,slow
仍然指向哑节点。
- 快慢指针同时移动:
- 当
fast
到达末尾5
时,slow
指向3
。
- 当
- 删除倒数第2个节点(即
4
):- 我们将
slow.next
指向5
,从而删除了4
。
- 我们将
- 返回结果:
- 返回哑节点的
next
,即修改后的链表0 -> 1 -> 2 -> 3 -> 5
(注意,我们实际返回的是1 -> 2 -> 3 -> 5
,因为哑节点不包含在结果中)。
- 返回哑节点的
Java代码示例:
public class ListNode { int val; ListNode next; ListNode(int x) { val = x; }
} public class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { // 创建一个哑节点(dummy node),指向头节点,方便处理头节点的删除 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; } // 删除慢指针指向的下一个节点(即倒数第n个节点) slow.next = slow.next.next; // 返回头节点(哑节点的下一个节点) return dummy.next; }
}
Python代码示例:
class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def removeNthFromEnd(head: ListNode, n: int) -> ListNode: # 创建一个哑节点(dummy node),指向头节点,方便处理头节点的删除 dummy = ListNode(0) dummy.next = head # 快慢指针初始化 fast = slow = dummy # 快指针先向前走n步 for _ in range(n): fast = fast.next # 快慢指针同时向前移动,直到快指针到达链表末尾 while fast.next: fast = fast.next slow = slow.next # 删除慢指针指向的下一个节点(即倒数第n个节点) slow.next = slow.next.next # 返回头节点(哑节点的下一个节点) return dummy.next