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

431 阅读2分钟

原题链接: 19. 删除链表的倒数第 N 个结点 - 力扣(Leetcode)

tag: 双指针, 链表.

一. 题目

给你一个链表, 删除链表的倒数第 n 个结点, 并且返回链表的头结点.

二. 题解

本题需要删除链表的倒数第 N 个节点.

先使用双指针的方法, 找到倒数第 N + 1 个节点(即倒数第 N 个节点的前驱节点).

再对链表中的第 N 个节点进行删除操作, 由于会涉及头删的情况, 所以我们设置一个虚拟头节点(dummy).

删除前.

image.png

设置一个虚拟头节点.

ListNode* dummy = new ListNode(0, head);

定义 slow 指针指向虚拟头节点, 定义 fast 指针指向头节点.

ListNode* slow = dummy, * fast = head;

image.png

由于 slow 指针和 fast 指针需要间隔 n + 1 步, 所以 fast 指针先走 n 步.

fast = fast->next;

image.png

fast = fast->next;

image.png

n == 0 时, 第一个 while 循环终止.

image.png

此时 fast 指针和 slow 指针间隔 n + 1 步, 在这之后我们同时使用 slowfast 对链表进行遍历.

image.png

slow = slow->next;

fast = fast->next;

image.png

重复这一步骤.

image.png

重复这一步骤.

image.png

fast == nullptr 时, 第二个 while 循环终止.

image.png

fast 指针遍历到链表末尾时(指向空), slow 指针恰好指向倒数第 N + 1 个节点, 即要删除的倒数第 N 个节点的前驱节点, 此时我们便可以对第 N 个节点进行删除操作了.

ListNode* temp = slow->next;

image.png

slow->next = temp->next;

image.png

delete temp;

image.png

删除链表的倒数第 N 个节点后返回链表的头节点.

head = dummy->next;

image.png

delete dummy;

image.png

删除后.

image.png

三. 复杂度分析

时间复杂度: O(N), 其中 N 是链表的长度.

空间复杂度: O(1).

四. 代码

/**
 * 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) {
        ListNode* dummy = new ListNode(0, head);    // 设置一个虚拟头节点
        ListNode* slow = dummy, * fast = head;    // 定义慢指针 slow, 快指针 fast
        while (n--) {    // 快指针先走 n 步
            fast = fast->next;
        } 
        while (fast != nullptr) {    // 快慢指针同时遍历链表
            slow = slow->next;
            fast = fast->next;
        }
        ListNode* temp = slow->next;    // 对链表中的第 N 个节点进行删除操作
        slow->next = temp->next;
        delete temp;

        head = dummy->next;    // 返回新的头节点
        delete dummy;
        return head;
    }
};