算法的学习笔记—删除链表中重复的结点(牛客JZ76)
😀前言
在链表操作中,删除重复节点是一个常见的问题。特别是在排序链表中,连续的重复节点不仅会影响链表的结构,还会带来额外的复杂度。本文将介绍一种高效的算法,用于删除链表中所有重复的节点,并保留链表中仅出现一次的节点。本文以 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}
😊解题思路
为了有效删除链表中的重复节点,可以采用递归的方法来遍历链表,并在过程中删除那些重复的节点。具体步骤如下:
- 递归处理链表:从链表头开始遍历链表,如果当前节点的值与其下一个节点的值相同,则说明当前节点是重复的。此时,我们需要跳过所有重复节点,将指针直接指向下一个不重复的节点。
- 删除重复节点:对于重复节点,通过递归调用,将指针指向第一个不重复的节点,从而删除所有重复节点。
- 保留唯一节点:如果当前节点的值与下一个节点的值不同,则当前节点是唯一的,可以保留。然后递归处理链表的其余部分。
😁代码实现
以下是基于上述思路的 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;
}
}
}
😀代码解析
- 入口方法
deleteDuplication
:- 首先判断链表是否为空,或者链表是否只有一个节点。如果是这种情况,直接返回当前链表头节点,因为此时没有重复节点需要处理。
- 取得当前节点的下一个节点
next
,并判断当前节点与next
是否具有相同的值。
- 处理重复节点:
- 如果当前节点的值与
next
的值相同,则说明当前节点是重复节点,需要删除。 - 通过循环跳过所有值相同的节点,直到找到一个值不同的节点。然后,递归调用
deleteDuplication
,处理下一个非重复节点。
- 如果当前节点的值与
- 处理非重复节点:
- 如果当前节点的值与
next
的值不同,则当前节点是唯一的。此时,只需递归处理链表的其余部分,并将当前节点连接到后续处理的结果上。
- 如果当前节点的值与
😆示例分析
假设输入链表为 1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5
,我们可以通过递归逐步删除重复节点,最终得到结果链表 1 -> 2 -> 5
。
- 初始链表为
1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5
。从头节点 1 开始,1 和 2 没有重复节点,因此保留。 - 遇到节点 3,发现其后面跟着另一个 3,因此跳过所有的 3,递归处理下一个不重复节点 4。
- 节点 4 与后面的节点值相同,也被删除,最后只保留节点 5。
😆时间与空间复杂度
- 时间复杂度:O(N),其中 N 是链表的节点数。每个节点只会被遍历一次,因此时间复杂度是线性的。
- 空间复杂度:O(N),递归调用栈的深度与链表长度有关,因此空间复杂度为 O(N)。
😄总结
本文介绍了一种删除排序链表中重复节点的高效算法。通过递归的方式,算法能够有效地删除所有重复节点,并保留链表中仅出现一次的节点。此方法的实现简单且易于理解,同时在时间和空间复杂度方面表现优异,适用于处理大规模数据链表中的重复节点问题。
- 点赞
- 收藏
- 关注作者
评论(0)