基础知识要求:
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代码示例:
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代码示例:
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