【Java】 劍指offer(18) 刪除鏈表中重複的結點

本文參考自《劍指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

完整Java代碼

    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: 
-----------
demo

 

收穫

  1.刪除多個結點時,只要把重複結點前一個結點的next指向重複結點的後一個結點;code

  2.不要把重複結點一個一個刪除,先定義一個布爾變量肯定當前結點是否重複,而後按上一句話的方法進行刪除便可。

 

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索