零、原题链接
一、题目描述
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
二、测试用例
示例 1:
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]
示例 2:
输入:head = [1,1,1,2,3]
输出:[2,3]
提示:
链表中节点数目在范围 [0, 300] 内
-100 <= Node.val <= 100
题目数据保证链表已经按升序 排列
三、解题思路
- 基本思路:
因为是已经升序,所以只要判断当前节点和后面节点是否相同,相同的节点全部删除即可。难点就是维护链表的完整性和判断节点为空的情况; - 具体思路:
- 定义指针:pre 指向待删除结点的前一个结点,p 指向当前节点;
- 给链表增加一个头指针,为了方便后续操作
- 遍历链表
- 若 p 与 q 相等,则开始删除结点:先存储值,删除与值相同的所有结点;
- 否则,则继续遍历下一个结点
四、参考代码
时间复杂度: O ( n ) \Omicron(n) O(n)
空间复杂度: O ( 1 ) \Omicron(1) O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* ans = new ListNode(0, head);
ListNode *pre = ans, *p = ans->next;
while (p != nullptr && p->next != nullptr) {
if (p->val == p->next->val) {
auto tVal = p->val;
while (p != nullptr && p->val == tVal) {
ListNode* t = p;
p = p->next;
delete t;
}
pre->next = p;
} else {
pre = pre->next;
p = p->next;
}
}
return ans->next;
}
};