力扣第19题 删除链表第n个节点

前言

记录一下刷题历程 力扣第19题 删除链表第n个节点


删除链表第n个节点

原题目:给你一个链表,删除链表的倒数第 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]

分析

我们根据下面这张图来解释一下
在这里插入图片描述
我们让L指针指向第一个节点,L指针向右移动两次让R指针指向第三个节点此时让L指针和R指针同时向右移动直到右指针指向NULL我们发现此时左指针指向我们要删除的节点。但是如果我们要删除倒数第二个节点,我们应该让图中的3的next指向5,所以我们让左指针事先指向链表的头节点Head,右指针仍然指向3这个节点,此时我们发现同时移动左右指针,当右指针指向NULL时左指针指向3,也就是我们想要删除的节点的前一个节点,此时让该节点的next指向该节点next的next即可完成删除。

代码如下:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // 创建一个虚拟头节点,方便处理删除头节点的情况
        ListNode* dummy = new ListNode(0, head);
        ListNode* left = dummy; // 初始化左指针为虚拟头节点
        ListNode* right = head; // 初始化右指针为链表头

        // 先让右指针前进 n 步
        while(n && right) {
            right = right->next;
            n--;
        }

        // 同时移动左指针和右指针,直到右指针到达链表末尾
        while(right) {
            left = left->next;
            right = right->next;
        }

        // 删除倒数第 n 个节点
        left->next = left->next->next;

        // 返回删除节点后的链表头(虚拟头节点的下一个节点)
        return dummy->next;
    }
};

解释注释

1.创建虚拟头节点:ListNode* dummy = new ListNode(0, head);

创建一个虚拟头节点 dummy,它的 next 指针指向原链表的头节点。这样做的好处是可以简化删除操作,包括删除头节点的情况。

2.初始化指针:

ListNode* left = dummy;:left 指针指向虚拟头节点。
ListNode* right = head;:right 指针指向链表的头节点。

3.移动右指针:

while(n && right):将 right 指针向前移动 n 步。
right = right->next;:每次移动一步,直到 right 指针前进了 n 步或者到达链表末尾。

4.同时移动左指针和右指针:

while(right):当 right 指针未到达链表末尾时,同时移动 left 和 right 指针。
这样,当 right 指针到达链表末尾时,left 指针正好在待删除节点的前一个节点。

5.删除目标节点:

left->next = left->next->next;:将 left 指针的下一个节点(即要删除的节点)跳过,从而删除该节点。
返回新链表头:

6.return dummy->next;:返回虚拟头节点的下一个节点,即删除目标节点后的链表头。

时间复杂度

因为只需要遍历一遍链表所以时间复杂度为O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值