算法的学习笔记—删除链表中重复的结点(牛客JZ76)

#如何高效记录并整理编程学习笔记?#

img

😀前言
在链表操作中,删除重复节点是一个常见的问题。特别是在排序链表中,连续的重复节点不仅会影响链表的结构,还会带来额外的复杂度。本文将介绍一种高效的算法,用于删除链表中所有重复的节点,并保留链表中仅出现一次的节点。本文以 Java 语言为例,进行详细的解读与实现。

🏠个人主页:尘觉主页

😆删除链表中重复的结点

牛客网

🥰题目描述

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。

示例
输入:1 -> 2 -> 2 -> 3 -> 3 -> 4
输出:1 -> 4
在上述例子中,节点 2 和节点 3 是重复的,因此它们及其所有的重复项都被删除,最终的链表只剩下 1 和 4。

数据范围:链表长度满足 0≤n≤1000 ,链表中的值满足 1≤val≤1000
进阶:空间复杂度 O(n) ,时间复杂度 O(n)

例如输入{1,2,2,3,2,4}时,对应的输出为{1,4},对应的输入输出链表如下图所示:

🤭示例1

输入:{1,2,3,3,4,4,5}
返回值:{1,2,5}

🤭示例2

输入:{1,1,1,8}
返回值:{8}

17e301df-52e8-4886-b593-841a16d13e44

😊解题思路

为了有效删除链表中的重复节点,可以采用递归的方法来遍历链表,并在过程中删除那些重复的节点。具体步骤如下:

  1. 递归处理链表:从链表头开始遍历链表,如果当前节点的值与其下一个节点的值相同,则说明当前节点是重复的。此时,我们需要跳过所有重复节点,将指针直接指向下一个不重复的节点。
  2. 删除重复节点:对于重复节点,通过递归调用,将指针指向第一个不重复的节点,从而删除所有重复节点。
  3. 保留唯一节点:如果当前节点的值与下一个节点的值不同,则当前节点是唯一的,可以保留。然后递归处理链表的其余部分。

😁代码实现

以下是基于上述思路的 Java 代码实现:

public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public class Solution {
    public ListNode deleteDuplication(ListNode pHead) {
        if (pHead == null || pHead.next == null)
            return pHead;
        
        ListNode next = pHead.next;
        
        // 当前节点是重复节点
        if (pHead.val == next.val) {
            // 跳过所有重复节点
            while (next != null && pHead.val == next.val) {
                next = next.next;
            }
            // 递归删除后续的重复节点
            return deleteDuplication(next);
        } 
        // 当前节点不是重复节点
        else {
            // 递归处理下一个节点
            pHead.next = deleteDuplication(pHead.next);
            return pHead;
        }
    }
}

😀代码解析

  1. 入口方法 deleteDuplication
    • 首先判断链表是否为空,或者链表是否只有一个节点。如果是这种情况,直接返回当前链表头节点,因为此时没有重复节点需要处理。
    • 取得当前节点的下一个节点 next,并判断当前节点与 next 是否具有相同的值。
  2. 处理重复节点
    • 如果当前节点的值与 next 的值相同,则说明当前节点是重复节点,需要删除。
    • 通过循环跳过所有值相同的节点,直到找到一个值不同的节点。然后,递归调用 deleteDuplication,处理下一个非重复节点。
  3. 处理非重复节点
    • 如果当前节点的值与 next 的值不同,则当前节点是唯一的。此时,只需递归处理链表的其余部分,并将当前节点连接到后续处理的结果上。

😆示例分析

假设输入链表为 1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5,我们可以通过递归逐步删除重复节点,最终得到结果链表 1 -> 2 -> 5

  1. 初始链表为 1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5。从头节点 1 开始,1 和 2 没有重复节点,因此保留。
  2. 遇到节点 3,发现其后面跟着另一个 3,因此跳过所有的 3,递归处理下一个不重复节点 4。
  3. 节点 4 与后面的节点值相同,也被删除,最后只保留节点 5。

😆时间与空间复杂度

  • 时间复杂度:O(N),其中 N 是链表的节点数。每个节点只会被遍历一次,因此时间复杂度是线性的。
  • 空间复杂度:O(N),递归调用栈的深度与链表长度有关,因此空间复杂度为 O(N)。

😄总结

本文介绍了一种删除排序链表中重复节点的高效算法。通过递归的方式,算法能够有效地删除所有重复节点,并保留链表中仅出现一次的节点。此方法的实现简单且易于理解,同时在时间和空间复杂度方面表现优异,适用于处理大规模数据链表中的重复节点问题。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

img

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘觉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值