題目:
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 }
