题目描述:
在一个排序好的链表中,删除所有重复的节点,将删除后的链表的头节点返回。
如果没有说明是经过排序的链表,那这个题目的难度将会增加一个等级。既然链表是经过排序的,因此所有重复的节点必定连在一起,因此只需要定义两个指针,一前一后遍历一遍链表即可,但是这个题目有一个难点,就是如何有效的返回这个头节点,因此,必须定义一个头节点,指向题目给出的头节点。
链表的结构体以及构造函数如下所示:
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
函数体如下所示
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
//定义并初始化一个节点指针
ListNode *head = new ListNode(-1);
//两个前后跑腿的节点指针
ListNode *pre;
ListNode *node;
//看看给的节点指针是不是空的,是不是一个独立的节点
if (pHead == nullptr)return nullptr;
if (pHead != nullptr&&pHead == nullptr)return pHead;
//将定义的头指针指向题目给出的节点指针
head->next = pHead;
pre = head;
node = pHead;
while (node) {
//将两个相邻的节点的值进行比较,只要是相同,而且下一个节点存在,就后移
if (node->next != nullptr&&node->val == node->next->val) {
node = node->next;
while (node->next != nullptr&&node->val == node->next->val) {
node = node->next;
}
//直到node的下一个节点的值与node不同,或者node下一个节点不存在,将node下移一个,然后pre继续指向node,千万这个地方不要越位
node = node->next;
pre->next = node;
}
else {
pre = node;
node = node->next;
}
}
return head->next;
}
};
最后一部分是main函数,里面主要放了一些测试数据
int main() {
ListNode *test;
ListNode *l0 = new ListNode(1);
ListNode *l1 = new ListNode(2);
ListNode *l2 = new ListNode(2);
ListNode *l3 = new ListNode(3);
ListNode *l4 = new ListNode(4);
ListNode *l5 = new ListNode(5);
l0->next = l1;
l1->next = l2;
l2->next = l3;
l3->next = l4;
l4->next = l5;
l5->next = NULL;
test = l0;
cout << "删除前链表的元素集合:" << endl;
while (test != nullptr) {
cout << test->val << " ";
test = test->next;
}
cout << endl << "删除后链表元素的集合:" << endl;
Solution s1;
test = s1.deleteDuplication(l0);
while (test!=nullptr) {
cout << test->val << " ";
test = test->next;
}
return 0;
}
最后再放一张测试结果图吧