本题的关键点在于不是单单删除重复的多余元素留下不重复的,而是要把重复的全部元素删除。这就导致在删除操作时,当指针指向的元素本身也需要删除时,需要记录一个前驱结点。
所以在最开始我们就需要定义一个虚拟头结点dummyhead,用于后续的寻找前驱操作。
另外,在每一次迭代后,都会有删除或者没有删除两种情况,我们可以先用flag区分该次迭代有没有进行过删除操作,再分情况考虑每种情况到下一次迭代开始的指针归位操作,更有条理一些。
代码如下:
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode cur=head;
if(head==null||head.next==null) {
return head;
}
//现在至少有两个结点了
//需加一个假的头结点
ListNode dummyhead=new ListNode(0);
dummyhead.next=head;
ListNode pre=dummyhead;//pre是cur的前驱结点
ListNode temp=head.next;
while(cur.next!=null) {
int flag=0;
while(temp.val==cur.val) {
//只要进了这个循环,cur本身也得删掉
flag=1;//表示有重复
temp=temp.next;
if(temp==null) break;
}
//此时,temp指向第一个值不等于cur的结点
//要删的是cur到temp的前一个结点
if(flag==1) {
pre.next=temp;
cur=temp;
if(temp!=null) {
temp=temp.next;
}
}
else {
cur=temp;
if(temp!=null) {
temp=temp.next;
}
pre=pre.next;
}
if(temp==null) break;
}
return dummyhead.next;
}
}