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

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

😀前言
在链表操作中,删除重复节点是一个常见的问题。特别是在排序链表中,连续的重复节点不仅会影响链表的结构,还会带来额外的复杂度。本文将介绍一种高效的算法,用于删除链表中所有重复的节点,并保留链表中仅出现一次的节点。本文以 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}

image.png

😊解题思路

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

  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)。

😄总结

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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