一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情。
题目描述
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
思路分析
由于数组已经排序,所以只需要遍历一遍即可。我们先考虑一种去重的算法,
输入: head = [1,2,3,3,4,4,5]
输出: [1,2,3,4,5]
这种算法很简单,只需要遍历每个节点的时候比较其pre节点,如果pre.val = node.val 则将node删除,pre节点保持不变。
而如果pre.val != node.val 则需要将pre节点后移一位,也就是node的位置,继续遍历
而如果要删除所有重复节点而不是简单的去重,那就难了。当pre.val = node.val 时, 则需要将pre节点前移,那样就需要有一个prepre节点,(当然由于链表本身是已经排序的,所以这种情况只会发生一次)
这样的话最初也要设置一下两个头节点
代码实现
ListNode* deleteDuplicates(ListNode* head) {
ListNode* reaHead = new ListNode(-101);
ListNode* preHead = new ListNode(-101);
reaHead -> next = preHead;
preHead -> next = head;
bool flag = false;
ListNode* prepre = reaHead;
ListNode* pre = preHead;
ListNode* node = head;
while(node != nullptr){
if(node->val == pre->val){
pre ->next = node -> next;
node = node -> next;
flag = true;
}else{
if(flag) {
prepre -> next = node;
pre = node;
node = node -> next;
flag = false;
}else{
node = node -> next;
pre = pre->next;
prepre = prepre -> next;
}
}
}
if(flag) {
// cout << prepre -> val;
// cout << "1" << endl;
prepre -> next = node;
pre = node;
// node = node -> next;
flag = false;
}
return reaHead -> next -> next;
}
总结
这道题其实难度并不是很大,不过实践中还是遇到了一些问题,比如【1,1】这种情况其实应该都删除,但是最初并没有在while外面加一层判断逻辑,导致会遗漏一个1.