本文參考自《劍指offer》一書,代碼採用Java語言。html
更多:《劍指Offer》Java實現合集 java
在一個排序的鏈表中,如何刪除重複的結點?例如,在圖3.4(a)中重複結點被刪除以後,鏈表如圖3.4(b)所示。面試
設置一個preNode,用於記錄當前結點的前一個結點,再設置一個布爾變量needDelete,若是當前結點和後一結點的值相同(記該值爲dupVal),needDelete賦值爲真。ide
當needDelete爲真時,經過循環日後找到第一個不爲dupVal的結點,把該結點設置爲當前結點,並賦值給preNode.next,即至關於完成了刪除操做;而當needDelete爲假時,把當前結點和preNode日後移一位便可。post
測試算例測試
1.功能測試(重複結點位於鏈表頭部、中部、尾部,無重複結點)this
2.特殊測試(null,全部結點均重複)url
public ListNode deleteDuplication(ListNode pHead){ ListNode pre = null; ListNode cur = pHead; while(cur!=null){ if(cur.next!=null && cur.next.val==cur.val){ while(cur.next!=null && cur.next.val==cur.val) cur=cur.next; cur=cur.next; if(pre==null) pHead=cur; else pre.next=cur; }else{ pre=cur; cur=cur.next; } } return pHead; }
(含測試代碼)spa
package _18; /** * * @Description 面試題18(二):刪除鏈表中重複的結點 * * @author yongh * @date 2018年9月18日 下午6:30:53 */ // 題目:在一個排序的鏈表中,如何刪除重複的結點?例如,在圖3.4(a)中重複 // 結點被刪除以後,鏈表如圖3.4(b)所示。 public class DeleteDuplicatedNode { class ListNode{ int val; ListNode next = null; ListNode(int val,ListNode next) { this.val = val; this.next=next; } } public ListNode deleteDuplication(ListNode pHead){ if(pHead==null||pHead.next==null) //空結點或者僅一個結點 return pHead; ListNode preNode = null; ListNode curNode = pHead; while(curNode!=null){ boolean needDelete=false; if(curNode.next!=null && curNode.val==curNode.next.val) needDelete=true; if(!needDelete){ //當前結點不重複 preNode=curNode; curNode=curNode.next; }else{ //當前結點重複 int dupValue=curNode.val; ListNode toBeDel = curNode; while(toBeDel!=null&&toBeDel.val==dupValue){ //這裏刪除暫時不涉及前一結點操做,其實主要是找出後面第一個不重複結點 toBeDel = toBeDel.next; } if(preNode==null){ //說明刪除的結點爲頭結點 pHead=toBeDel; }else{ preNode.next=toBeDel; } curNode=toBeDel; //這個結點仍是可能會出現重複的,因此不能=next } } return pHead; } //========測試代碼====== void test(ListNode pHead) { System.out.println("-----------"); System.out.print("The original list is: "); ListNode curr=pHead; if(curr!=null) { while(curr.next!=null) { System.out.print(curr.val+","); curr=curr.next; } System.out.println(curr.val); }else { System.out.println(); } pHead=deleteDuplication(pHead); System.out.print("The result list is: "); curr=pHead; if(curr!=null) { while(curr.next!=null) { System.out.print(curr.val+","); curr=curr.next; } System.out.println(curr.val); }else { System.out.println(); } System.out.println("-----------"); } /** * 重複結點位於鏈表頭部 */ void test1() { ListNode p4=new ListNode(3, null); ListNode p3=new ListNode(2, p4); ListNode p2=new ListNode(1, p3); ListNode p1=new ListNode(1, p2); test(p1); } /** * 重複結點位於鏈表尾部 */ void test2() { ListNode p4=new ListNode(3, null); ListNode p3=new ListNode(3, p4); ListNode p2=new ListNode(2, p3); ListNode p1=new ListNode(1, p2); test(p1); } /** * 重複結點位於鏈表中部 */ void test3() { ListNode p4=new ListNode(3, null); ListNode p3=new ListNode(2, p4); ListNode p2=new ListNode(2, p3); ListNode p1=new ListNode(1, p2); test(p1); } /** * 連續出現重複結點 */ void test4() { ListNode p6=new ListNode(3, null); ListNode p5=new ListNode(3, p6); ListNode p4=new ListNode(2, p5); ListNode p3=new ListNode(2, p4); ListNode p2=new ListNode(1, p3); ListNode p1=new ListNode(1, p2); test(p1); } /** * 多個重複結點 */ void test5() { ListNode p6=new ListNode(3, null); ListNode p5=new ListNode(3, p6); ListNode p4=new ListNode(3, p5); ListNode p3=new ListNode(2, p4); ListNode p2=new ListNode(1, p3); ListNode p1=new ListNode(1, p2); test(p1); } /** * 無重複結點 */ void test6() { ListNode p6=new ListNode(6, null); ListNode p5=new ListNode(5, p6); ListNode p4=new ListNode(4, p5); ListNode p3=new ListNode(3, p4); ListNode p2=new ListNode(2, p3); ListNode p1=new ListNode(1, p2); test(p1); } /** * 單個結點 */ void test7() { ListNode p1=new ListNode(6, null); test(p1); } /** * null */ void test8() { ListNode p1=null; test(p1); } public static void main(String[] args) { DeleteDuplicatedNode demo= new DeleteDuplicatedNode(); demo.test1(); demo.test2(); demo.test3(); demo.test4(); demo.test5(); demo.test6(); demo.test7(); demo.test8(); } }
----------- The original list is: 1,1,2,3 The result list is: 2,3 ----------- ----------- The original list is: 1,2,3,3 The result list is: 1,2 ----------- ----------- The original list is: 1,2,2,3 The result list is: 1,3 ----------- ----------- The original list is: 1,1,2,2,3,3 The result list is: ----------- ----------- The original list is: 1,1,2,3,3,3 The result list is: 2 ----------- ----------- The original list is: 1,2,3,4,5,6 The result list is: 1,2,3,4,5,6 ----------- ----------- The original list is: 6 The result list is: 6 ----------- ----------- The original list is: The result list is: -----------
1.刪除多個結點時,只要把重複結點前一個結點的next指向重複結點的後一個結點;code
2.不要把重複結點一個一個刪除,先定義一個布爾變量肯定當前結點是否重複,而後按上一句話的方法進行刪除便可。