解题思路:创建一个假头(类似:21. 合并两个有序链表这题),构建一条新的链表,按照不重复添加原则来添加节点
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode temp=head;
//创建一个假头
ListNode dummy=new ListNode(-1000,head);
ListNode low=dummy;//指向前一个节点的指针
while(temp!=null){
if(low.val!= temp.val){
low.next=temp;
temp=temp.next;
low=low.next;
low.next=null;//防止到最后一个不重复节点时,还有有连接到重复元素的,保证链表的末尾节点是空
}else{
temp=temp.next;//原链表直接下移指针,low在新的链表不用改变
}
}
return dummy.next;
}
}
low.next=null;//防止到最后一个不重复节点时,还有有连接到重复元素的,保证链表的末尾节点是空(这句话不能省)
(这道题比较难!!!)
这里需要设置两个pre和prepre指针来辅助,为了pre是为了比较重复元素并记录重复元素的值,便于后续删除。而prepre这个相当于是以有效的连接下一个新值结点的作用。
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null) return null;
ListNode dummy=new ListNode(-1000);//创建一个假头,指向有效链表的头结点
dummy.next=head;
ListNode prepre=dummy;
ListNode pre=head;
ListNode temp=pre.next;
while(temp!=null){
//遇到重复节点
if(pre.val== temp.val){
while(temp!=null){
if(temp.val!= pre.val){
break;
}
temp=temp.next;//下一个新值的节点
}
//移动并删除节点
prepre.next=temp;
pre=temp;
if(temp!=null){
temp=temp.next;
}
continue;//进入下一轮新值节点的判断
}
//由于是不重复节点,所以继续向后移动指针
prepre=pre;
pre=temp;
temp=temp.next;
}
return dummy.next;
}
}
注意:执行任何temp的next和val成员变量时,确保这个temp不是null,否则null即temp是没有next和val的(注意:是先判断非null,再判断值是否相等,如果两个条件的顺序反了,会编译出现null没法获取val的异常)