算法的学习笔记—在 O(1) 时间内删除链表节点

举报
尘觉 发表于 2024/08/13 11:53:45 2024/08/13
【摘要】 在链表操作中,删除节点是一个常见的操作。然而,如何在最短的时间内完成删除节点的操作是一个值得探讨的问题。通常情况下,删除链表节点需要遍历链表来找到目标节点及其前驱节点,时间复杂度为 O(N)。但是,通过巧妙的设计,可以在 O(1) 的时间内完成删除操作。本文将详细介绍这一算法及其实现。

😀前言
在链表操作中,删除节点是一个常见的操作。然而,如何在最短的时间内完成删除节点的操作是一个值得探讨的问题。通常情况下,删除链表节点需要遍历链表来找到目标节点及其前驱节点,时间复杂度为 O(N)。但是,通过巧妙的设计,可以在 O(1) 的时间内完成删除操作。本文将详细介绍这一算法及其实现。

😆在 O(1) 时间内删除链表节点

😋解题思路

我们可以将删除节点的操作分为两种情况来处理:

🤔情况 1:删除的节点不是尾节点

如果要删除的节点不是链表的尾节点,那么我们可以通过以下步骤来实现删除:

  1. 将下一个节点的值赋给当前节点:例如,我们要删除节点 A,可以将 A 的下一个节点 B 的值复制到 A。
  2. 调整指针:令 A 指向 B 的下一个节点,从而跳过节点 B。
  3. 删除节点 B:这样,节点 A 依然存在于链表中,但它的值和位置实际上已经是原节点 B 的值和位置,节点 B 被删除了。

这一过程无需遍历链表,时间复杂度为 O(1)。
image.png

🤔情况 2:删除的节点是尾节点

如果要删除的节点是链表的尾节点,处理就会稍微复杂一些:

  1. 遍历链表:找到要删除节点的前一个节点。
  2. 调整指针:将前一个节点的 next 指针置为 null,从而删除尾节点。

由于需要遍历整个链表来找到前驱节点,因此时间复杂度为 O(N)。

image.png

综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N ~ 2,因此该算法的平均时间复杂度为 O(1)。

😃Java 实现

以下是上述思路的 Java 实现:

public ListNode deleteNode(ListNode head, ListNode tobeDelete) {
    if (head == null || tobeDelete == null)
        return null;
    if (tobeDelete.next != null) {
        // 要删除的节点不是尾节点
        ListNode next = tobeDelete.next;
        tobeDelete.val = next.val;
        tobeDelete.next = next.next;
    } else {
        if (head == tobeDelete)
             // 只有一个节点
            head = null;
        else {
            ListNode cur = head;
            while (cur.next != tobeDelete)
                cur = cur.next;
            cur.next = null;
        }
    }
    return head;
}

🥰代码解析

  1. 入口方法 deleteNode
    • 处理特殊情况:首先检查输入的链表头节点和要删除的节点是否为 null,若是则直接返回 null
    • 如果要删除的节点不是尾节点,直接将下一个节点的值复制到当前节点,调整当前节点的 next 指针,跳过下一个节点。
    • 如果要删除的节点是尾节点,则需要遍历链表找到前驱节点,并将前驱节点的 next 指针置为 null
  2. 处理尾节点
    • 如果链表只有一个节点,直接将链表头设为 null
    • 如果链表有多个节点,则遍历链表找到尾节点的前驱节点,并调整指针。

😊示例分析

假设链表为 1 -> 2 -> 3 -> 4 -> 5,我们要删除节点 3。根据上面的算法,节点 3 将被节点 4 的值覆盖,链表变为 1 -> 2 -> 4 -> 4 -> 5。随后,节点 4 的 next 指向节点 5,最终链表变为 1 -> 2 -> 4 -> 5,实现了删除节点 3 的效果。

😄总结

本文介绍了一种在 O(1) 时间内删除链表节点的算法,通过区分要删除的节点是否为尾节点来进行不同的处理。对于非尾节点,可以通过复制和指针调整在常数时间内完成删除操作;对于尾节点,则需要遍历链表找到前驱节点,时间复杂度为 O(N)。整体来看,该算法的平均时间复杂度为 O(1),是处理链表删除问题的高效方法。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。