1. 题目
描述
给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。
例如:
给出的链表为1→2→3→3→4→4→5, 返回1→2→5.
给出的链表为1→1→1→2→3 返回2→3.
数据范围:链表长度 0≤n≤100000 ,链表中的值满足 ∣val∣≤1000
要求:空间复杂度 O(n),时间复杂度 O(n)
进阶:空间复杂度 O(1),时间复杂度 O(n)
示例1
输入:
{1,2,2}
返回值:
{1}
示例2
输入:
{}
返回值:
{}
2. 解题思路
本题要求删除重复的元素即在链表中重复的元素都会被删除,由于重复的元素也有可能是头结点,因此需要定义一个链表的虚拟头结点,虚拟头结点的指针域指向链表的头结点。
假如链表结构如下图所示:
这时可以通过以下步骤完成链表重复元素的删除。
步骤一:定义虚拟头结点、指针变量。
cur :链表节点衔接指针(当前操作的节点);
nxt1:操作的下一个节点;
nxt2 :操作的下下一个节点。
步骤二:循环删除链表的重复节点。
此时,nxt1与nxt2对应的节点值都是1(重复的元素),移动nxt2。
此时,nxt1与nxt2对应的节点值还是1(重复的元素),移动nxt2。
这时,nxt1的节点值是1,nxt2的值是2,需将已经检查出重复的元素1删除。删除重复元素1可以通过更改cur当前节点的指针域,让它指向nxt2,这样就可以将多个1节点删除。
之后再移动nxt1与nxt2,使得nxt1始终指向当前操作节点cur的下一个节点;nxt2始终指向当前操作节点cur的下下一个节点。
ntx1 = cur.next # 下一个节点
ntx2 = cur.next.next # 下下一个节点
此时,nxt1与ntx2对应的节点值都是2(重复的元素),移动nxt2。
这时,nxt1的节点值是2,nxt2的值是3,需将已经检查出重复的元素2删除。删除重复元素2可以通过更改cur当前节点的指针域,让它指向nxt2,这样就可以将多个2节点删除。
之后再移动nxt1与nxt2,这时发现nxt1与nxt2中有一个为Null,循环退出(重复元素删除完成)。
步骤三:返回链表中无重复节点组成的链表头结点。
虚拟头节点的下一个节点就是需要返回的链表头节点,将其返回。
如果文字描述的不太清楚,你可以参考视频的详细讲解。
- Python版本:https://www.bilibili.com/cheese/play/ep1370403
- Java版本:https://www.bilibili.com/cheese/play/ep1366847
- Golang版本:https://www.bilibili.com/cheese/play/ep1364604
3. 编码实现
核心伪代码如下:
函数 删除重复节点(头节点 head) 返回 链表节点:
如果 head 为空:
返回 head
//1. 定义虚拟头结点、指针变量
创建虚拟头节点 tmp_head,值为 -1
tmp_head的下一个节点指向 head
当前节点 cur 指向 tmp_head
//2. 循环删除链表的重复节点
当 cur的下一个节点 不为空 且 cur的下一个节点的下一个节点 不为空 时,循环执行:
ntx1 = cur的下一个节点
ntx2 = cur的下一个节点的下一个节点
如果 ntx1的值 == ntx2的值:
val = ntx1的值
当 ntx2 不为空 且 ntx2的值 == val 时,循环执行:
ntx2 = ntx2的下一个节点
cur的下一个节点 = ntx2 # 跳过所有重复节点
否则:
cur = cur的下一个节点 # 移动指针到下一个非重复节点
// 3.返回链表中无重复节点组成的链表头结点
返回 tmp_head的下一个节点 # 返回处理后的链表头节点
具体完整代码你可以参考下面视频的详细讲解。
- Python版本:https://www.bilibili.com/cheese/play/ep1370403
- Java版本:https://www.bilibili.com/cheese/play/ep1366847
- Golang版本:https://www.bilibili.com/cheese/play/ep1364604
4.小结
本题要求删除重复的元素即在链表中重复的元素都会被删除,由于重复的元素也有可能是头结点,因此需要定义一个链表的虚拟头结点,虚拟头结点的指针域指向链表的头结点。
这时可以通过以下步骤完成链表重复元素的删除。(1)定义虚拟头结点、指针变量;(2)循环删除链表的重复节点;(3)返回链表中无重复节点组成的链表头结点。
《数据结构与算法》深度精讲课程正式上线啦!七大核心算法模块全解析:
✅ 链表 ✅ 二叉树 ✅二分查找、排序 ✅ 堆、栈、队列 ✅回溯算法 ✅ 哈希算法 ✅ 动态规划
无论你是备战笔试面试、提升代码效率,还是突破技术瓶颈,这套课程都将为你构建扎实的算法思维底座。🔥立即加入学习打卡,与千名开发者共同进阶!
- Python编码实现:https://www.bilibili.com/cheese/play/ep1509965
- Java编码实现:https://www.bilibili.com/cheese/play/ep1510007
- Golang编码实现:https://www.bilibili.com/cheese/play/ep1509945
对于链表的相关操作,我们总结了一套【可视化+图解】方法,依据此方法来解决链表相关问题,链表操作变得易于理解,写出来的代码可读性高也不容易出错。具体也可以参考视频详细讲解。
今日佳句:千淘万漉虽辛苦,吹尽狂沙始到金。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。