題目:
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given 1->2->3->3->4->4->5
, return 1->2->5
.
Given 1->1->1->2->3
, return 2->3
.
題解:
這道題與I的區別就是要把所有重複的node刪除。因此,還是利用I中去重的方法,引用雙指標,並且增加一個新的指標,指向當前的前一個node,使用3個指標(prev,current,post)來遍歷連結串列。
最開始還是需要建立一個fakehead,讓fakehead的next指向head。然後,使用我剛才說過的3個指標方法來初始化3個指標,如下:
ListNode ptr0 = fakehead; //prev
ListNode ptr1 = fakehead.next;
//current
ListNode ptr2 = fakehead.next.next; //post
同時還需要引入一個布林型的判斷flag,來幫助判斷當前是否遇到有重複,這個flag能幫助識別是否需要刪除重複。
當沒有遇到重複值(flag為false)時,3個指標同時往後移動:
ptr0 = ptr1;
ptr1 = ptr2;
ptr2 = ptr2.next;
當遇到重複值時,設定flag為true,並讓ptr2一直往後找找到第一個與ptr1值不等的位置時停止,這時,ptr1指向的node的值是一個重複值,需要刪除,所以這時就需要讓ptr0的next連上當前的ptr2,這樣就把所有重複值略過了。然後,讓ptr1和ptr2往後挪動繼續查詢。
這裡還需要注意的是,當ptr2一直往後找的過程中,是有可能ptr2==null(這種情況就是list的最後幾個元素是重複的,例如1->2->3->3->null),這時ptr1指向的值肯定是需要被刪除的,所以要特殊處理,令ptr0的next等於null,把重複值刪掉。其他情況說明最後幾個元素不重複,不需要處理結尾,遍歷就夠了。
程式碼如下:
2 if(head == null || head.next == null)
3 return head;
4
5 ListNode fakehead = new ListNode(0);
6 fakehead.next = head;
7
8 ListNode ptr0 = fakehead;
9 ListNode ptr1 = fakehead.next;
10 ListNode ptr2 = fakehead.next.next;
11
12 boolean flag = false;
13 while(ptr2!=null){
14 if(ptr1.val == ptr2.val){
15 flag = true;
16 ptr2 = ptr2.next;
17 if(ptr2 == null)
18 ptr0.next = null;
19 }else{
20 if(flag){
21 ptr0.next = ptr2;
22 flag = false;
23 }else{
24 ptr0 = ptr1;
25 }
26 ptr1 = ptr2;
27 ptr2 = ptr2.next;
28 }
29 }
30 return fakehead.next;
31 }