</pre><pre code_snippet_id="1928155" snippet_file_name="blog_20161013_2_4408641" name="code" class="java">
</pre><pre name="code" class="java">/**************************************************************
* Copyright (c) 2016,
* All rights reserved.
* 版 本 號:v1.0
* 題目描述:刪除重複鏈表
* 在一個排序的鏈表中,刪除其中的重複節點,例如,鏈表A:
A:1->2->2->4->4->6 刪除重複節點後的鏈表B爲:
B:1->4->6.
*
* 輸入描述:無
* 程序輸出:算法1:刪除節點後的鏈表是:
* 2->6->null
* 算法2:刪除節點後的鏈表是:
* 2->6->null
* 問題分析: 無
* 算法描述: 解決這個問題的第一步是確定刪除的參數。當然這個函數需要輸入待刪除鏈表的頭結點。頭結點可能與後面的結點重複,
* 也就是說頭結點也可能被刪除,所以在鏈表頭添加一個結點。
* 接下來我們從頭遍歷整個鏈表。如果當前結點的值與下一個結點的值相同,那麼它們就是重複的結點,
* 都可以被刪除。爲了保證刪除之後的鏈表仍然是相連的而沒有中間斷開,
* 我們要把當前的前一個結點和後面值比當前結點的值要大的結點相連。我們要確保prev要始終與下一個沒有重複的結點連接在一起。
* 算法2:採用遞歸調用的方式
* 完成日期:2016-10-13
***************************************************************/
package org.marsguo.offerproject57;
class ListNode{
int val;
ListNode next;
public ListNode(){
}
public ListNode(int val){
this.val = val;
}
public String toString(){
return val + "";
}
}
class SolutionMethod1{
public ListNode deletNodeFunction(ListNode head){
if(head == null)
return null;
ListNode root = new ListNode(); //新定義一個root節點
root.next = head;
ListNode preNode = root; //前驅節點
ListNode pNode = head; //當前處理的節點
//preNode.next = head;
while(pNode != null && pNode.next != null){
//相鄰兩個節點值相同,刪除相同節點
if(pNode.val == pNode.next.val){
while(pNode.next != null && pNode.next.val == pNode.val){
pNode = pNode.next;
}
preNode.next= pNode.next;
}
//相鄰兩個節點值不相同,保留pNode,並向後移動
else{
preNode.next = pNode;
preNode = preNode.next;
}
pNode = pNode.next;
}
/*
返回的鏈表是從root開始打印,因爲root從頭開始,而preNode和pNode最後都指向了末尾節點
*/
return root.next;
//return preNode.next;
}
public void print(ListNode head){
while(head != null){
System.out.print(head + "->");
head = head.next;
}
System.out.println("null");
}
}
class SolutionMethod2 extends SolutionMethod1{ //採用繼承SolutionMethod1,直接調用print方法
public ListNode deleteDuplicationFun(ListNode head){
if(head == null)
return null;
if(head != null && head.next == null)
return head;
ListNode current;
if(head.next.val == head.val){
current = head.next.next;
//while循環用於刪除連續重複的節點,直到下一個不是重複的
while(current != null && current.val == head.val)
current = current.next;
return deleteDuplicationFun(current); //遞歸調用,最終將鏈表連起來
}
else{
current = head.next;
head.next = deleteDuplicationFun(current); //採用遞歸調用
return head;
}
/*public void print(ListNode head){ //重複代碼,採用繼承可以避免
while(head != null){
System.out.print(head + "->");
head = head.next;
}
System.out.println("null");
}*/
}
}
public class DeleteDuplicationNode {
public static void main(String[] args){
ListNode n1 = new ListNode(1);
ListNode n2 = new ListNode(1);
ListNode n3 = new ListNode(2);
ListNode n4 = new ListNode(4);
ListNode n5 = new ListNode(4);
ListNode n6 = new ListNode(6);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
SolutionMethod1 solution1 = new SolutionMethod1();
System.out.println("算法1:刪除節點後的鏈表是:" );
ListNode result = solution1.deletNodeFunction(n1);
solution1.print(result);
SolutionMethod2 solution2 = new SolutionMethod2();
System.out.println("算法2:刪除節點後的鏈表是:");
ListNode result2 = solution2.deleteDuplicationFun(n1);
solution2.print(result2);
System.out.println();
}
}
程序運行結果: