题目描述
原始题目参考:删除有序链表的重复元素
给定一个已排序的链表的头 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; }