1、题目描述
存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。
返回同样按升序排列的结果链表。
示例
提示
- 链表中节点数目在范围 [0, 300] 内
- -100 <= Node.val <= 100
- 题目数据保证链表已经按升序排列
2、思路
- 1 创建虚拟头节点(该节点内部不存储具体元素,只做链表头)
Node dummyHead=new Node(101);
- 2 判断重复元素
当cur.val!=next.val时,prev,cur,next统一向后移动一位,
当cur.val==next.val时,cur不动,next一直向下走,
直到cur.val!=next.val,此时说明[cur,next)都是要删除的元素。
此时:
prev–第一个重复节点的前驱
next–最后一个重复节点的后继
(prev,next)中间元素都是要删除的
- 3 删除元素
prev.next=next;
3、代码
// 删除链表中所有重复节点,重复节点都不保留
public class num82 {
// 101 1 2 3 3 4 4 5
// 1.判断重复元素
// 三个引用 prev cur next
// prev=101 cur=1 next=2
// if cur.val!=next.val prev cur next都像后移动一个单位
//prev=1 cur=2 next=3 继续
// prev=2 cur=3 next=3 此时next继续向后移动,直到走到next.val!=cur.val,next走到第一个与cur不等得节点
// 此时,prev是重复节点得前驱,next 重复节点得后继 prev到next之间的元素都是要删除的
// 删除 prev.next=next;
public ListNode deleteDuplicates(ListNode head) {
// 创建虚拟头节点
ListNode dummyHead=new ListNode(101);
dummyHead.next=head;
ListNode prev=dummyHead;
ListNode cur=prev.next;
while(cur!=null){
ListNode next=cur.next;
if(next==null){
// 此时链表只有一个节点
return dummyHead.next;
}
else{
if(cur.val!=next.val){
// 三引用向后移动
prev=prev.next;
cur=cur.next;
}
else{
// 链表中不止一个节点
// 前面的if(next==null),只是判断刚开始的next,next会移动,所以此时还需要判断next是否为空
while(next!=null&&cur.val==next.val){
next=next.next;
}
}
// 此时prev走向第一个重复节点的前驱
// next指向重复节点得后继
prev.next=next;
// 更新cur的指向
cur=next;
}
}
return dummyHead.next;
}
}