在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
题目来源:牛客网https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef?tpId
题目分析:
有序链表相邻的元素必然在一起,比较链表元素的值。
分析过程
递归方法
注意
- 考虑当链表为空时,和链表只有一个节点时的情况
- 注意
cur && pHead->val==cur->val
这个条件,对于结点重复两次以上,有很重要的作用。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead==NULL || pHead->next==NULL)
{
return pHead;
}
ListNode* cur;
if(pHead->val == pHead->next->val)
{
cur = pHead->next->next;
while(cur && pHead->val==cur->val)
{
cur=cur->next;
}
return deleteDuplication(cur);
}
else
{
cur=pHead->next;
pHead->next=deleteDuplication(cur);
return pHead;
}
}
};
非递归方法
过程如图:
注意
- 解释一下,为什么最后不返回
pHead
,因为如果头结点就是重复的呢,那删除了以后,就找不到pHead
这个头了,所以,新建的一个结点来作为头,这个新的头的下一个节点始终是链表的头结点。
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead==NULL || pHead->next==NULL)
{
return pHead;
}
ListNode* head=new ListNode(0);
head->next=pHead;
ListNode* prev=head;
ListNode* cur=head->next;
while(cur){
if(cur->next && cur->val==cur->next->val)
{
while(cur->next && cur->val==cur->next->val)
{
cur=cur->next;
}
prev->next=cur->next;
cur=cur->next;
}
else{
prev=prev->next;
cur=cur->next;
}
}
return head->next;
}
};