题目说明
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/description/
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字
解法1
该解法只使用一层循环,遍历链表,每次判断当前点与下一个结点的值是否相等,若相等,则删除下一个结点。但是这样与当前点所有相等的结点都删除后,无法判断当前是否需要删除,所以添加了一个标识位来判断是否需要删除当前点。
特别地当遍历链表结点后,还需要判断一个标识位,因为可能最后一个点因为无法满足遍历条件而不能被处理。
这种方法有些繁琐,推荐下面两种方法。
/*
* 时间复杂度:O(n)
* 遍历链表,若cur的下一个结点与cur的值相等,则删除下一结点,并标记cur为待删除结点(delflag = 1)
* 直到不再有相等的,再将cur删除,并将delflag置0
*/
ListNode* deleteDuplicates(ListNode* head) {
ListNode *dummy = new ListNode(0);
dummy->next = head;
ListNode *pre = dummy;
ListNode *cur = NULL;
ListNode *next = NULL;
int delflag = 0;
while(pre->next && pre->next->next){
cur = pre->next;
next = pre->next->next;
if (cur->val == next->val){
cur->next = next->next;
delflag = 1;
delete next;
} else{
if (delflag == 1){
delflag = 0;
pre->next = cur->next;
delete cur;
continue;
}
pre = pre->next;
}
}
if (delflag == 1){
pre->next = cur->next;
delete cur;
}
return dummy->next;
}
解法2
当判断到有相等结点时,开启循环找到所有相等的点,遇到相等的点,则删除相等的前一个点,遍历指针后移。这样遍历过程只保留最后一个相等的结点。最后再将该结点删除即可。
/*
* 时间复杂度:O(n)
* 与上一种解法不同的是,遇到相等的点,删除相等前一个点,遍历指针后移
* 遇到了相等的点,开始遍历找到所有相等的点也是需要借鉴的
*/
ListNode* deleteDuplicates(ListNode* head) {
ListNode *dummy = new ListNode(0);
dummy->next = head;
ListNode *pre = dummy;
ListNode *cur = NULL;
ListNode *del = NULL;
while(pre->next){
cur = pre->next;
if (cur->next && cur->val == cur->next->val){
int x = cur->val;
while (cur->next && cur->next->val == x){
del = cur;
cur = cur->next;
delete del;
}
pre->next = cur->next;
delete cur;
} else
pre = pre->next;
}
return dummy->next;
}
解法3
借鉴第二种解法2,改造第一种解法。
/*
* 时间复杂度:O(n)
* 根据第二种解法改造第一种解法
* 遇到了相等的结点,则进行循环遍历,找到所有相等的点
* 与第二种解法不同的是 这里是删除新找到的结点
*/
ListNode* deleteDuplicates(ListNode* head) {
ListNode *dummy = new ListNode(0);
dummy->next = head;
ListNode *pre = dummy;
ListNode *cur = NULL;
ListNode *del = NULL;
while(pre->next) {
cur = pre->next;
if (cur->next && cur->next->val == cur->val) {
int x = cur->val;
while (cur->next && cur->next->val == x) {
del = cur->next;
cur->next = cur->next->next;
delete del;
}
pre->next = cur->next;
delete cur;
} else
pre = pre->next;
}
return dummy->next;
}