【LeetCode & 剑指offer刷题】链表题4:22 删除链表中倒数第k个结点(19. Remove Nth Node From End of List)

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

19. Remove Nth Node From End of List

Given a linked list, remove the n-th node from the end of list and return its head.
Example:
Given linked list: 1->2->3->4->5, and n = 2.
 
After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Follow up:
Could you do this in one pass?
 
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/*方法:双指针法,前面的指针比后面的领先n+1步,往前走,直到前面的指针到达末尾结点,所要信息,可以从落后的指针获取
如果只是查找倒数第n个结点,可以只用领先n步即可
 
fast领先n+1步,
fast到nullptr,slow到达倒数n+1位置
删除倒数n位置结点即可
(prehead的使用)
*/
class Solution
{
public:
    ListNode* removeNthFromEnd(ListNode* head, int n)
    {
        //防御性编程
        if(head == nullptr || n == 0) return head;
       
        ListNode prehead(0); //创建头结点,方便处理只有一个结点或者移除首结点的特殊情况
        prehead.next = head; //指向首结点
        ListNode* fast = &prehead, *slow = &prehead;
       
        //fast领先n+1步,循环退出时,fast在位置n+1,slow在位置0(prehead位置为0)
        for(int i = 1; i<=n+1; i++)
        {
            fast = fast->next;
        //    if(fast == nullptr) return nullptr; //对于查找,需要处理如果n小于链表长度的情况
        }
       
        //同时移动fast和slow
        while(fast != nullptr)
        {
            fast = fast->next;
            slow = slow->next;
        } //结果为fast指向最后一个结点之后为nullptr,slow指向倒数第(n+1)个结点 (找到倒数第n+1个结点,方便删除下一个结点)
       
        ListNode* temp = slow->next; //倒数第n个结点
        slow->next = slow->next->next; //跳过倒数第n个结点
        delete temp; //删除倒数第n个结点
       
        return prehead.next;
       
    }
};
/*
方法二
class Solution
{
public:
    ListNode* removeNthFromEnd(ListNode* head, int n)
    {
        if(head == NULL || n <= 0)
            return head;
        if(head->next == NULL)
            return NULL;
       
        ListNode *p1 = head, *p2 = head;
        while(n > 0)
        {
            p1 = p1->next;
            n --;
        }
        if(p1 == NULL) // 要删除的为head节点
        {        
            head = head->next;
            delete p2;
            return head;
        }
       
        ListNode *pre = head;
        while(p1 != NULL)
        {
            pre = p2;
            p1 = p1->next;
            p2 = p2->next;
        }
        pre->next = p2->next;
        delete p2;
        return head;
    }
};
*/
 
原文地址:https://www.cnblogs.com/wikiwen/p/10225178.html