题目描述
题目:输入一条链表,删除链表的中的重复节点,链表有序,且重复节点不保留,返回头结点指针,链表节点结构定义如下:
struct ListNode {
int val;
ListNode *next;
ListNode(int x)
: val(x), next(NULL)
{}
};
例如:链表1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5,处理后的结果为:1 -> 2 -> 5
解题思路
- 针对于此题,我们首先想到的是:将其分为重复和不重复两部分来进行讨论
- 首先,从头节点开始遍历,若有两个节点的值是重复的,那么从当前节点开始遍历直到找到一个节点与前面值都不重复的
- 从头结点开始遍历,如果两个节点的值不是重复的,那么我们需要将其与跳过重复部分后面的链表链接起来
- 我们发现,整个链表的遍历过程中,我们一直在做重复上面两步的操作,所以我们很容易就可能想到递归的解决方式,思路理清楚后,我们就可以写代码了
代码实现
ListNode* deleteDuplication(ListNode* pHead)
{
//若链表为空或者只有一个节点,则返回头节点
if(pHead == NULL || pHead->next == NULL)
return pHead;
//处理重复节点
ListNode* cur = NULL;
if(pHead->val == pHead->next->val)
{
cur = pHead->next;
//找到与前面节点不重复的节点
while(cur != NULL && cur->val == pHead->val)
{
cur = cur->next;
}//此时,cur为空,或者它与前面节点不重复
//删除前面重复节点,从cur节点开始,继续判断
return deleteDuplication(cur);
}
else //处理非重复节点
{
//pHead->val != pHead->next->val
cur = pHead->next;
pHead->next = deleteDuplication(cur);
return pHead;
}
}
- 完整代码实现+非递归版本:
ListNode* deleteDuplication(ListNode* pHead)
{
if (pHead == NULL || pHead->next == NULL)
return pHead;
ListNode* cur = NULL;
if (pHead->val == pHead->next->val)
{
cur = pHead->next->next;
while (cur != NULL && cur->val == pHead->val)
{
cur = cur->next;
}
//返回第一个非重复节点,作为链表的头
return deleteDuplication(cur);
}
else
{
cur = pHead->next;
//将去除了重复节点后的前后链表链接起来
pHead->next = deleteDuplication(cur);
return pHead;
}
}
//非递归版本
ListNode* deleteDuplicationNonR(ListNode* pHead)
{
if (pHead == NULL || pHead->next == NULL)
return pHead;
//新建一个节点,防止头结点被删除
ListNode* pNew = new ListNode(-1);
pNew->next = pHead;
ListNode* prev = pNew;
ListNode* cur = pHead;
ListNode* next = NULL;
while (cur != NULL && cur->next != NULL)
{
next = cur->next;
if (cur->val == cur->next->val)
{
while (next != NULL && next->val == cur->val)
{
next = next->next;
}
prev->next = next;
cur = next;
}
else
{
prev = cur;
cur = cur->next;
}
}
return pNew->next;
}
void PrintList(ListNode* head)
{
while (head != NULL)
{
printf("%d ->", head->val);
head = head->next;
}
printf("over\n");
}
int main()
{
ListNode* node1 = new ListNode(1);
ListNode* node2 = new ListNode(2);
ListNode* node3 = new ListNode(3);
ListNode* node31 = new ListNode(3);
ListNode* node4 = new ListNode(4);
ListNode* node41 = new ListNode(4);
ListNode* node5 = new ListNode(5);
node1->next = node2;
node2->next = node3;
node3->next = node31;
node31->next = node4;
node4->next = node41;
node41->next = node5;
cout << "before:" << endl;
PrintList(node1);
cout << "after:" << endl;
ListNode* head = deleteDuplication(node1);
//ListNode* head = deleteDuplicationNonR(node1);
PrintList(head);
return 0;
}
- 运行结果如下: