删除链表的倒数第n个节点(LeetCode)

原题来自牛客网LeetCode:链接

题目描述

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

例如,给出的链表为:1->2->3->4->5, n= 2.
删除了链表的倒数第n个节点之后,链表变为1->2->3->5.

备注:

  • 题目保证n一定是有效的
  • 请给出请给出时间复杂度为O(n)的算法

思路

使用双指针,先让一个指针走出n步,然后开始让两个指针一起移动,直到先出发的指针到达尽头。因为二者的距离一直为n,所以最终后出发的指针所处位置即倒数第n个结点。

需要注意,因为找到的是倒数第n个结点,而删除时我们需要知道倒数第n+1个结点,因此需要加以控制,因此下方代码判断的是while(p->next!=nullptr)而不是while(p->next!=nullptr)。

这题还有个坑点,有可能删除的是头结点,因此要通过判断先出发的指针是否已经变成nullptr,如果是那说明要删的是头结点(具体原因自己数数就知道了)。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head==nullptr||head->next==nullptr)
            return nullptr;
        ListNode *p=head,*pre=head,*tmp;
        //第一个指针先动n步
        for(int i=0;i<n&&p!=nullptr;i++)
            p=p->next;
        //讨论删除头结点的特殊情况
        if(p==nullptr){
            tmp=head->next;
            delete head;
            return tmp;
        }
    	//一起移动
        while(p->next!=nullptr){  //为了知道倒数第n+1个结点,所以判断p->next!=nullptr
            p=p->next;
            pre=pre->next;
        }
        tmp=pre->next;
        pre->next=pre->next->next;
        delete tmp;
        return head;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值