存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。
返回同样按升序排列的结果链表。
示例1:最终结果返回最初的head节点
示例2:最终结果返回n2节点
思路:用三个节点判断是否有重复节点,重点是找到重复节点将其跳过并且明确最终应该返回哪个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(head == nullptr)
{
return nullptr;
}
ListNode *n1,*n2,*n3;
n1 = nullptr;
n2 = head;
n3 = n2->next;
while(n3)
{
if(n2->val != n3->val)//n2 n3不相等,直接一起往后找
{
n1 = n2;
n2 = n3;
n3 = n3->next;
}
else//n2 == n3
{
//找到[n2,n3)的重复区间
while(n3 && n2->val == n3->val)
{
n3 = n3->next;
}
//删除重复区间
while(n2 != n3)
{
//ListNode* next = n2->next;
//delete n2;
//n2 = next;
n2 = n2->next;//上面3行是对重复的节点进行了删除,这一行没有对重复节点删除,只是跳过它们找到满足题意的节点(这一行的效率要比前三行高很多)
}
if(n1 != nullptr)
{
n1->next = n2;
}
else//最前面就有节点相等的话,此时的起始节点应该是n2
{
head = n2;
}
if(n3 != nullptr)//此时n3已经为空时,应该结束往后找的操作
{
n3 = n3->next;
}
}
}
return head;
}
};
后记:本题折磨了我很久,从开始判空时就把情况搞反了,导致结果一直是空;其次对于链表各种情况的判断也琢磨了好久