题目:
在一个排序(保证重复节点连在一块)的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。如 输入链表:1->2->3->3->4->4->5 ,处理后为:1->2->5
解析 :
要想删除重复节点有两个关键点需要解决:
- 确定新的头结点。因为对于原链表来说,头结点可能是重复节点,所以也可能会被删除
- 如何保证删除重复节点以后,仍然保证链表保持连接,而不会断开。
思路:
几个关键变量:
1. cur:指向当前遍历到的节点
2. pre:指向最近一个不重复节点,也就是已经选取出来的不含有重复节点的链表的尾节点(注意pre不是指向cur 的前一个节点)。当还未发现不重复节点时,pre = null。pre 是保持链表连读的关键,pre式中与剩余链表保持连接
3. next:指向cur的下一个节点
4. head:表示可能的头结点。因为当pre = null时,表示还未发现不重复的节点,head指向的是可能的都节点,一旦pre != null,则head的值即为不含有重复节点的链表的头结点。
过程:
初始时,head指向原链表的头结点,pre = null。
步骤1:遍历链表,当前遍历节点为cur,next指向下一个节点,如果节点cur的值与next的值不相同,则执行步骤2;否则表示当前节点和下一个节点是重复节点,都需要删除,执行步骤3
步骤2:令pre = cur,并且cur指向写一个节点
步骤3:从cur继续向后遍历节点,直到发现与节点cur的值不同的节点next(保证当前遍历到的重复节点位于pre与next之间),如果此时pre = null,说明还未发现不重复的节点,则将head指向可能的头结点next。如果pre 不是null,则将pre与next中间重复的节点删除,即将pre的下一个节点指向next。当前节点cur指向next,然后重复执行步骤1
java代码:
public ListNode deleteDuplication(ListNode pHead){
if(pHead == null)
return null;
ListNode head = pHead;
ListNode pre = null;
ListNode cur = pHead;
while(cur != null){
Boolean toBeDelete = false;
ListNode next = cur.next;
//步骤1
if(next != null && cur.val == next.val){
toBeDelete = true;
}
//步骤2
if(toBeDelete != true){
pre = cur;
cur = next;
}else{
//步骤3
while(next != null && cur.val == next.val){
cur = next;
next = next.next;
}
if(pre == null){
head = next;
cur = next;
}else{
pre.next = next;
cur = next;
}
}
}
return head;
}