如图:只要是重复元素就删除,那么我们是不是可以认为这是一个过河问题,其中重复的元素表示不稳固或者假石头(让head踩),非重复元素表示可以真石头,可以踩(pre可以到达)。当前面的把石头踩过之后(重复元素都被删除)返回头结点(cur->next),给后面的人过
那么如此我们需要判断哪些真那些假:
思路:遇到链表就需要设立两个节点指针,一个cur一个pre,分别表示记录pre的起始位置和不重复位置。初始化pre,cur都为nullstr,那么head再往后移动的过程中遇到重复字符就一直跳(往后移),pre不动,而跳到重复字符末尾时需要判断是否是到了末尾,不是末尾则继续跳,此时pre->next指向head,但是pre还不能移,因为不确定head此时指向的新字符是否为重复字符,要继续循环判断,不是就一直找到一个非重复字符,找到后pre才移到head,head后移,最后返回cur->next头指针
/**
* 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||head->next==nullptr)return head;
ListNode* pre=new ListNode(-1);
pre->next=head;
ListNode*cur=pre;
while(head->next!=nullptr){
if(head->val==head->next->val) {
head=head->next;
if(head->next&&head->val!=head->next->val){//只有head下一个值不重复时才让pre->next指向head,否则就head就一直跳此时pre不能移防止head依然和后面重复
head=head->next;
pre->next=head;
}
else if(!head->next){//如果head到末尾,pre也直接结束
pre->next=nullptr;
}
}
else{//只有head->next有着落同时只有head前后都不重复时pre才往后移
pre=head;
head=head->next;//head继续往后判断有没有重复
}
}
return cur->next;
}
};