删除排序链表中的重复元素
题目描述
原始题目参考:删除有序链表的重复元素
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]
示例 2:
输入:head = [1,1,1,2,3]
输出:[2,3]
解题思路
递归
以示例1为例,链表序列为[1,2,3,3,4,4,5]
,求该链表的无重复链表可以简化为求[2,3,3,4,4,5]
和[1]
的拼接,再到求[1,2]
和[3,3,4,4,5]
的拼接,可以看到[3,3,4,4,5]
链表开头有重复,所以去重复数字3
的结果链表为[4,4,5]
,再求其结果为[5]
,最终的结果为[1,2,5]
。
参考代码
ListNode* deleteDuplicates(ListNode* head) {
if(head==nullptr||head->next==nullptr){
return head;
}
ListNode* last=head->next;
if(head->val==last->val){
while(last!=nullptr && head->val==last->val){
last=last->next;
}
head=deleteDuplicates(last);
}
else{
head->next=deleteDuplicates(last);
}
return head;
}
指针遍历
需要初始一个临时结点指向head
结点,然后再遍历中去除重复的元素,让指针指向未重复过的元素。
还是以示例1为例:
[1,2,3,3,4,4,5]
,添加头节点变为:[0,1,2,3,3,4,4,5]
;cur为头节点0
,判断1
和2
是否一样,cur指向1
;cur为头节点1
,判断2
和3
是否一样,cur指向2
;cur为头节点2
,判断3
和3
是否一样,x为3
,进行内层while循环,cur->next从第一个3
指向第二个3
;判断x
和4
是否一样,x为3
,跳出内层while循环,cur->next指向第一个4
;判断4
和4
是否一样,x为4
,进行内层while循环,cur->next从第一个4
指向第二个4
;判断x
和4
是否一样,x为4
,跳出内层while循环,cur->next指向5
;cur指向5
,结束程序。
参考代码
ListNode* deleteDuplicates(ListNode* head) {
if(head==nullptr||head->next==nullptr){
return head;
}
ListNode* temp=new ListNode(0,head);
ListNode* cur=temp;
while(cur->next&&cur->next->next){
if(cur->next->val==cur->next->next->val){
int x=cur->next->val;
while(cur->next!=nullptr && x==cur->next->val){
cur->next=cur->next->next;
}
}
else{
cur=cur->next;
}
}
return temp->next;
}