题目描述
给定一个已排序的链表的头head,删除所有重复的元素,使每个元素只出现一次。返回 已排序的链表。
例如:
输入:head = [1,1,2]
输出:[1,2]
输入:head = [1,1,2,3,3]
输出:[1,2,3]
来源:Leetcode 83
地址:https://leetcode.cn/problems/remove-duplicates-from-sorted-list/
//c++,链表结点的结构
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){};
};
思路
思路1: 遍历链表结点,存储每个结点的值,某结点的值已经在set中出现过,就删去该结点,使该结点的上一个结点指向该结点的下一个结点。如果该结点的值没出现过,就把该值加入到set中。
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
unordered_set<int> set;
struct ListNode* tmp = new ListNode(0, head);
struct ListNode* newhead = tmp;
while(tmp->next != nullptr){
if(set.count(tmp->next->val)){
tmp->next = tmp->next->next;
}else{
set.insert(tmp->next->val);
tmp = tmp->next;
}
}
return newhead->next;
}
};
思路2: 迭代法。tmp用于保存头结点,然后对tmp进行迭代。比较(tmp)的val,与下一个结点(tmp->next)的val,如果两个val相等,就让tmp指向tmp->next->next,跳过tmp->next这个结点;如果前面提到的两个val不相等,则无需删去,让tmp前进到tmp->next。重复上面过程,不断循环,直到tmp->next为nullptr,循环结束。
class Solution{
public:
ListNode* deleteDuplicates(ListNode* head){
ListNode* tmp = head;
if(head==nullptr) return head;
while(tmp->next != nullptr){
if(tmp->val == tmp->next->val){
tmp->next = tmp->next->next;
}else{
tmp = tmp->next;
}
}
return head;
}
};
思路3: 递归。“递”的终止条件是进行到链表最后一个结点,返回该结点;“归”的时候,不断比较当前结点与“归”过程返回的结点,如果两者的val相等,就删去“归”结点。继续下一次递归。“归”过程返回的结点其实就是当前结点的下一个结点,实际上仍是在比较相邻两个结点的val。递归结束时,head就是当前链表的头结点,直接返回即可。
class Solution{
public:
ListNode* deleteDuplicates(ListNode* head){
if(head->next == nullptr){
return head;
}
ListNode* tmp = deleteDuplicates(head->next);
if(head->val == tmp->val){
head->next = tmp->next;
// head->next = head->next->next;
}
return head;
}
};