删除链表的倒数第N个结点

删除链表的倒数第N个结点

在这里插入图片描述

题目解析:
思路一:(带有头节点的版本)
  • 采取双重遍历肯定是可以解决问题的,但题目要求我们一次遍历解决问题,那我们的思路得发散一下。
  • 我们可以设想假设设定了双指针 p 和 q 的话,当 q 指向末尾的 NULL,p 与 q 之间相隔的元素个数为 n 时,那么删除掉 p 的下一个指针就完成了要求。
  • 设置虚拟节点 dummyHead 指向 head
  • 设定双指针 p 和 q,初始都指向虚拟节点 dummyHead
  • 移动 q,直到 p 与 q 之间相隔的元素个数为 n
  • 同时移动 p 与 q,直到 q 指向的为 NULL
  • 将 p 的下一个节点指向下下个节点
  • 让快慢指针相差n个位置,当快指针到最后一个元素时,慢指针的下一个元素正好就是要删除的元素
代码如下所示:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) 
    {  
        ListNode *start = new ListNode(-1);             //建立一个新的头结点
        start->next = head;
        ListNode *slow = start , *fast = start , *temp; 
        for(int i = 1; i <= n ; i++)    
        {
            fast = fast->next;  
        }
        while(fast->next)
        {
            slow = slow->next;
            fast = fast->next;
        }
        temp=slow->next;
        slow->next=slow->next->next;
        delete temp; 
        return start->next;             //head可能被删除了,所以用start->next表示新的头结点
    }
};
思路二:(不带头节点的版本)

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
    ListNode *slow = head , *fast = head; 
    ListNode *temp;
    for(int i = 1; i <= n ; i++)    
        fast = fast->next;
    if(fast == NULL)            //只有当要删除头结点时,fast==NULL,n恰好等于链表的元素个数
    {
        temp = head->next;
        delete head;
        return temp;            //返回新的头结点
    }
    while(fast->next)
    {
        slow = slow->next;
        fast = fast->next;
    }
    temp=slow->next;
    slow->next=slow->next->next;
    delete temp;
    return head;
    }
};
思路三:递归

class Solution {
public:
    int cur=0;
    ListNode* removeNthFromEnd(ListNode* head, int n) 
    {
       if(nullptr==head)        
           return NULL;
       head->next = removeNthFromEnd(head->next,n);
       if(n == ++cur)      
           return head->next;              
       return head;
    }
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值