【双指针 快慢指针】19 删除链表倒数第N个元素

本文介绍了一种高效算法,用于删除链表中倒数第N个节点,通过两次遍历或使用双指针技巧实现,适用于各种链表规模,包括极端情况。

题目

给定一个链表,删除链表的倒数第n个节点,并且返回头结点

分析

两次遍历:首先第一次遍历的得到长度。
第二次遍历时,因为删除节点需要有被删除节点的前一个节点。考虑到只有一个节点、两个节点的情况这种极端情况。需要定义一个head前指针

代码

ListNode p1 = head;
int len=0;
while(p1!=null){
    len++;
    p1 = p1.next;
}
int rem = len-n;
/*因为删除节点需要有被删除节点的前一个节点。
考虑到只有一个节点、两个节点的情况
需要定义一个head前指针
* */
ListNode prehead = new ListNode(0);
prehead.next = head;
ListNode curhead = prehead;
while(rem!=0){

    curhead = curhead.next;
    rem--;

}
curhead.next = curhead.next.next;
return prehead.next;

分析

一次遍历。使用两个指针。先让快指针走一定距离,然后和慢指针一起走,当快指针到达结尾null时慢指针正好的到达被删除结点 的pre。

代码

ListNode prehead = new ListNode(0);
prehead.next = head;
ListNode first = prehead;
ListNode second = prehead;
for(int i=1;i<=n+1;i++){
    first = first.next;
}
while(first!=null){
    first = first.next;
    second = second.next;
}
second.next = second.next.next;
return prehead.next;
### 删除链表倒数第n个节点 在处理链表操作时,删除链表倒数第n个节点是一个经典问题。为了高效地解决这个问题,通常可以采用双指针的方法。 #### 双指针方法 这种方法的核心思想是使用两个指针,一个快指针(`fast`)和一个慢指针(`slow`)。通过调整这两个指针之间的距离,可以在一次遍历中找到并删除链表倒数第n个节点。 1. **初始化**:创建一个虚拟头节点(`dummy`),并将它的`next`指向原始链表的头节点。这样做的目的是为了简化对头节点的特殊处理。 2. **移动快指针**:让快指针先向前移动`n`步。这样,快指针和慢指针之间就保持了`n`的距离。 3. **同时移动快慢指针**:接下来,同时移动快指针和慢指针,直到快指针到达链表的末尾。此时,慢指针将位于倒数第`n+1`个节点的位置。 4. **删除节点**:通过修改慢指针所指节点的`next`属性,跳过倒数第`n`个节点,从而实现删除操作。 以下是具体的代码实现: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next class Solution: def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: dummy = ListNode(0) dummy.next = head fast = dummy 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 ``` #### 时间复杂度分析 - **时间复杂度**:O(L),其中L是链表的长度。我们只需要进行一次遍历。 - **空间复杂度**:O(1),只使用了常数级别的额外空间。 #### 特殊情况处理 - 如果链表只有一个节点,并且需要删除该节点,则直接返回`None`。 - 通过使用虚拟头节点,可以简化对头节点的删除操作[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值