题目:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
思路:首先这是一个已经排序好的链表,所以从头开始遍历碰到重复的不输出。可以采用循环的方法,也可以采取递归的方法。
以1->2->2->2->4->4->5为例,演示下示过程,帮助理解
代码1:循环
问题:return出现问题
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == nullptr || pHead->next == nullptr)
return;
ListNode* pPreNode = nullptr;
ListNode* pNode = pHead;
while(pNode != nullptr){
ListNode* pNext = pNode->next;
bool needDelete = false;
if(pNext != nullptr && pNext->val == pNode->val)
needDelete = true;
if(!needDelete){
//如果false,则当前节点赋值给前节点,下一个节点赋值给当前节点
pPreNode = pNode;
pNode = pNode->next;
}
else{
//如果下一个节点pNext的值与pNode的值相同,存储该值
int value = pNode->val;
//如果pNode的值与pNext相同,定义一个指针用来存储当前待删除的节点
ListNode* toBeDelete = pNode;
while(toBeDelete != nullptr && toBeDelete->val == value){
pNext = toBeDelete->next;
delete toBeDelete;
toBeDelete = nullptr;
toBeDelete = pNext;
if(pPreNode == nullptr)
pHead = pNext;
else
pPreNode->next = pNext;
pNode = pNext;
}
}
}
return pHead;
}
};
代码2:递归
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == nullptr || pHead->next == nullptr)
return pHead;
ListNode* current;
if(pHead->val == pHead->next->val){
current = pHead->next->next;
while(current != nullptr && current->val == pHead->val)
//跳过与当前节点不同的节点,直到第一个与当前节点不同的节点。
current = current->next;
//从第一个与当前结点不同的结点开始递归
return deleteDuplication(current);
}
else{
current = pHead->next;
//如果当前节点不是重复节点,则保留当前节点,从下一个结点开始递归
pHead->next = deleteDuplication(current);
return pHead;
}
}
};
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == nullptr || pHead->next == nullptr)
return pHead;
ListNode* p = pHead;
ListNode* head = new ListNode(pHead->val+1);
head->next = p;
ListNode* q = head;
while(p){
//值相等,指针p后移
while(p->next && p->next->val == p->val){
p = p->next;
}
//没有相等的值,两个指针都往后移
if(q->next == p){
p = p->next;
q = q->next;
}
else{
q->next = p->next;
p = p->next;
}
}
return head->next;
}
};
代码3:讨论区还有一种方法,创建一个头节点和两个指针p、q
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if(pHead == nullptr || pHead->next == nullptr)
return pHead;
ListNode* p = pHead;
//新建一个头节点head,令他的值为真正的头节点的值+1
ListNode* head = new ListNode(pHead->val+1);
//定义两个指针p、q。;两个指针用来比较节点的值
//p指向自建的头节点head的下一个节点pHead(也就是真正的头节点)
head->next = p;
//新建头节点q、指向自己定义的头节点
ListNode* q = head;
while(p){
//值相等,指针p后移
while(p->next && p->next->val == p->val){
p = p->next;
}
//没有相等的值,两个指针都往后移
if(q->next == p){
p = p->next;
q = q->next;
}
else{
//如果两个节点指向的值相等,令q的next指向p的next,调过相同的节点
q->next = p->next;
p = p->next;
}
}
//从真正的头节点pHead开始返回值
return head->next;
}
};