【LeetCode】19. 删除链表的倒数第 N 个结点

19. 删除链表的倒数第 N 个结点(中等)

在这里插入图片描述

【LeetCode】19. 删除链表的倒数第 N 个结点_第1张图片

【LeetCode】19. 删除链表的倒数第 N 个结点_第2张图片

方法:快慢指针

思路

  • 为了找到倒数第 n 个节点,我们应该先找到最后一个节点,然后从它开始往前数 n-1 个节点就是要删除的节点。

  • 对于一般情况:设置 fast 和 slow 两个指针,分别指向「最后一个节点」和「要删除的节点的前一个节点」(这里是为了方便实现删除操作)。

    由于 fast 和 slow 最后指向的节点之间相距 n-1 步,因此我们先让 fast 走 n 步,同时需要保证 fast->next 不为空。

    接着令 fast 和 slow 同时前进,直到 fast 到达最后一个节点,此时 slow 指向 「要删除的节点的前一个节点」或者「要删除的节点」(当头节点需要删除的时候),修改 slow->next ,这样就删除了指定节点。

  • 对于节点数为 1 的特殊情况,必然是删除这个唯一的节点,因此直接将 head 指向 nullptr。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // 当链表里只有一个节点,直接删除该节点
        if(!head->next) {
            head = nullptr;
            return head;
        }
        // 设置快慢指针
        ListNode *fast = head, *slow = head;
        // 在保证fast->next不为空的情况下,使fast比slow多走n步
        while(n >= 1 && fast->next) {
            fast = fast->next;
            n--;
        }
        // 当fast遍历到最后一个节点,说明slow已经走到倒数第n+1个节点
        // 这里将slow指向倒数第n+1个节点,是为了方便删除倒数第n个节点
        while(fast->next) {
            slow = slow->next;
            fast = fast->next;
        }
        // 当倒数第n个节点是头节点,特殊处理
        if(slow == head && n > 0) head = slow->next;
        // 否则删除第n个节点
        else slow->next = slow->next->next;
        return head;
        
    }
};

你可能感兴趣的:(LeetCode刷题,leetcode,链表,算法)