原题目
面试题 02.01. 移除重复节点
编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。
示例1:
输入:[1, 2, 3, 3, 2, 1]
输出:[1, 2, 3]
示例2:
输入:[1, 1, 1, 1, 2]
输出:[1, 2]
提示:
- 链表长度在[0, 20000]范围内。
- 链表元素在[0, 20000]范围内。
进阶:
如果不得使用临时缓冲区,该怎么解决?
第一遍解法
思路,从前至后依次访问节点,使用set容器保存pre节点的值,若cur节点的值在set容器中存在,则删除。否则访问下一个节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeDuplicateNodes(ListNode* head) {
ListNode *pre = NULL;
ListNode *cur = head;
unordered_set<int> elements;
while (cur != NULL) {
if (elements.find(cur->val) != elements.end()) {
pre->next = cur->next;
}
else {
elements.insert(cur->val);
pre = cur;
}
cur = cur->next;
}
return head;
}
};
时间复杂度: O(n)
空间复杂度: O(n)
如果不得使用临时缓冲区,该怎么解决?
使用双重循环遍历。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeDuplicateNodes(ListNode* head) {
ListNode *pre = head;
while (pre != NULL) {
ListNode *cur = pre;
while (cur != NULL && cur->next != NULL) {
if (pre->val == cur->next->val) {
cur->next = cur->next->next;
}
else {
cur = cur->next;
}
}
pre = pre->next;
}
return head;
}
};
时间复杂度: O(n^2)
空间复杂度: O(1)
网上好的解法
思路与第一次解法一致。
用集合:
class Solution {
public:
ListNode* removeDuplicateNodes(ListNode* head) {
if (head == nullptr) {
return head;
}
unordered_set<int> occurred = {head->val};
ListNode* pos = head;
// 枚举前驱节点
while (pos->next != nullptr) {
// 当前待删除节点
ListNode* cur = pos->next;
if (!occurred.count(cur->val)) {
occurred.insert(cur->val);
pos = pos->next;
} else {
pos->next = pos->next->next;
}
}
pos->next = nullptr;
return head;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/remove-duplicate-node-lcci/solution/yi-chu-zhong-fu-jie-dian-by-leetcode-solution/
来源:力扣(LeetCode)
双重循环:
class Solution {
public:
ListNode* removeDuplicateNodes(ListNode* head) {
ListNode* ob = head;
while (ob != nullptr) {
ListNode* oc = ob;
while (oc->next != nullptr) {
if (oc->next->val == ob->val) {
oc->next = oc->next->next;
} else {
oc = oc->next;
}
}
ob = ob->next;
}
return head;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/remove-duplicate-node-lcci/solution/yi-chu-zhong-fu-jie-dian-by-leetcode-solution/
来源:力扣(LeetCode)
最后的代码
与第一次解法一致。
小结
- unordered_set集合的find,若查找失败,返回iterator::end()。