刪除連結串列中重複的結點——牛客劍指offer
題目描述:
在一個排序的連結串列中,存在重複的結點,請刪除該連結串列中重複的結點,重複的結點不保留,返回連結串列頭指標。 例如,連結串列1->2->3->3->4->4->5 處理後為 1->2->5
解題思路:
首先初始化一個起始指標preNode指向頭結點、工作指標walkNode指向連結串列的第一個元素,即preNode.next=walkNode。
迭代開始:
while(walkNode!=null){
如果當前工作結點的資料域walkNode.val與下一個結點的資料域walkNode.next.val相同(出現重複結點):
preNode不移動;(指向重複結點段的前一個結點)
walkNode移動:walkNode=walkNode.next;(此時preNode.next!=walkNode)
否則,
如果preNode.next==walkNode(說明未出現重複節點):
preNode移動,walkNode移動:preNode=walkNode;walkNode=walkNode.next;
否則,說明有重複結點,此時preNode指向重複結點段的前一個結點,walkNode指向重複結點段的最後一個重複結點
使preNode直接指向重複結點段的下一個結點:preNode.next=walkNode.next;
walkNode移動:walkNode=walkNode.next;
}
注意:因為可能會刪除頭結點,例如{1,1,1,2},刪除了頭結點1和第一個結點1,結果應為{2}。但是如果直接將函式傳進來的pHead作為頭結點,即初始化preNode=pHead,那麼頭節點永遠不可能被刪除,得到的結果只能為{1,2}。
因此這裡添加了一個新的頭節點newhead,將pHead當一般結點處理,初始化preNode=newhead這樣就可以避免出現上面的錯誤。
舉例:
1->2->3->3->4->4 (加入新頭結點newhead:newhead.val=0,;ewhead.next=pHead) 0->1->2->3->3->4->4
初始化:
preNode指向新的頭結點,walkNode指向第一個結點
preNode=newNode
walkNode=newhead.next
第1次迭代:
walkNode1與其下一個結點2不相同,而且preNode0和walkNode1相鄰,說明之前也沒有出現過重複結點,所以把兩個指標都前移
walkNode.next.val!=walkNode.val&&pre.next==walkNode:pre=walkNode;walkNode=walkNode.next;
第2次迭代:
同第一次迭代
walkNode.next.val!=walkNode.val&&pre.next==walkNode:pre=walkNode;walkNode=walkNode.next;
第3次迭代:
walkNode3與下一個結點3重複,那麼此時preNode不移動,只移動walkNode
walkNode.next.val==walkNode.val:walkNode=walkNode.next
第4次迭代:
walkNode3與其下一個結點4不相同,但是此時preNode和walkNode不相鄰,說明preNode和walkNode中間出現了重複結點,所以把preNode直接指向walkNode的下一個結點,拋棄中間重複節點
walkNode.next.val!=walkNode.val&&pre.next!=walkNode:pre.next=walkNode.next;walkNode=walkNode.next;
第5次迭代:
walkNode4與下一個結點4重複,那麼此時preNode不移動,只移動walkNode
walkNode.next.val==walkNode.val:walkNode=walkNode.next
第6次迭代:
walkNode.next==null&&pre.next!=walkNode:pre.next=walkNode.next;return newNode.next;
程式碼實現
package struct;
public class deleteList {
//public class ListNode {
// int val;
// ListNode next = null;
// ListNode(int val) {
// this.val = val;
// }
//}
public ListNode printListFromTailToHead(ListNode pHead) {
ListNode newhead=new ListNode(0);//解決刪除頭結點的可能,例如{1,1,1,1,2}
newhead.next=pHead;
ListNode pre=newhead;
ListNode walkNode=newhead.next;
while(walkNode!=null){
if(walkNode.next!=null){
if(walkNode.next.val!=walkNode.val){
if(pre.next!=walkNode)
{
pre.next=walkNode.next;
}
else
{
pre=walkNode;
}
}
}
else{ //如果walkNode指向最後一個結點
if(pre.next!=walkNode)
{
pre.next=walkNode.next;
}
else
{
pre=walkNode;
}
}
walkNode=walkNode.next;
}
return newhead.next;
}
}