Leetcode 2095. 删除链表的中间节点

146 阅读2分钟

原题链接: 2095. 删除链表的中间节点 - 力扣(Leetcode)

tag: 双指针, 链表.

在阅读本文前, 请先阅读如下两篇题解.

Leetcode 876. 链表的中间结点 - 掘金 (juejin.cn)

Leetcode 19. 删除链表的倒数第 N 个结点 - 掘金 (juejin.cn)

一. 题目

给你一个链表的头节点 head . 删除 链表的 中间节点 , 并返回修改后的链表的头节点 head .

长度为 n 链表的中间节点是从头数起第 ⌊n / 2⌋ 个节点(下标从 0 开始), 其中 ⌊x⌋ 表示小于或等于 x 的最大整数.

  • 对于 n = 1234 和 5 的情况, 中间节点的下标分别是 0112 和 2 .

二. 题解

本题需要删除链表的中间节点, 则我们需要找到链表中间节点的前驱节点.

使用 快慢指针法 找到链表的中间节点.

定义 prev 指针保存 slow 指向节点的前一个节点从而定位中间节点的前驱节点.

image.png

定义一个虚拟头节点 dummy , 定义 prev 指针用来标记被删除节点的前驱节点.

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

image.png

定义慢指针 slow, 快指针 fast.

ListNode* slow = head, * fast = head;

image.png

fast != nullptr && fast->next != nullptr;

image.png

用 prev 指针维护 slow 节点的前驱节点.

prev = slow;

image.png

慢指针走一步.

slow = slow->next;

image.png

快指针走两步.

fast = fast->next->next;

image.png

重复这一步骤直至 fast == nullptr 或 fast->next == nullptr .

image.png

删除链表的中间节点.

prev->next = slow->next;

image.png

delete slow;

image.png

返回新链表的头节点.

head = dummy->next;

image.png

delete dummy;

image.png

return head;

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* deleteMiddle(ListNode* head) {
        ListNode* dummy = new ListNode(0, head), * prev = dummy;    // 定义一个虚拟头节点 dummy , 定义 prev 指针用来标记被删除节点的前驱节点
        ListNode* slow = head, * fast = head;    // 定义慢指针 slow, 快指针 fast
        while (fast && fast->next) {
            prev = slow;    // 用 prev 指针维护 slow 节点的前驱节点
            slow = slow->next;    // 慢指针走一步
            fast = fast->next->next;    // 快指针走两步
        }
        prev->next = slow->next;    // 删除链表的中间节点
        delete slow;

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