Question 
 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.
本题难度Medium。
【复杂度】 
 时间 O(N) 空间 O(1) 
【思路】 
 我在开始想出两个办法:
- 遇到重复的就删除
- 对重复的部分考察完毕后再整体删除
方法1有个麻烦:第一个重复数最后要另外删除。所以我使用方法2,为了便于理解我利用三个指针prev、fst、cur(两个指针也可可以fst=prev.next),prev指向上一个不同的数的node,fst指向本次重复数的第一个node,cur指向现在考察的node。例如:
..->1 ->2 ->2 ->2->3->..
| | |
prev fst cur
- 如果cur.val==fst.val,cur向后移动一位
- 如果cur.val!=fst.val(这个就是关键了):
如果 fst.next!=cur 说明该数有重复,就进行整体删除
否则,说明该数没有重复,就将`prev、fst、cur`都向前移动一位。
【附】 
 使用了fake是为了对只有一个node的情况进行处理
【注意】
- 这个方法对head=null的情况不能处理,所以有12-13行的处理
- 29-30行是为了对例如:1->1这种情况进行处理。
- 返回是 return fake.next;
【代码】
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode deleteDuplicates(ListNode head) {
//require
if(head==null)
return head;
ListNode fake=new ListNode(-1);
fake.next=head;head=fake;
//invariant
ListNode prev=head,fst=prev.next,cur=fst;
while(cur!=null){
if(cur.val!=fst.val){
if(fst.next!=cur)
prev.next=cur;
else
prev=fst;
fst=cur;
}
cur=cur.next;
}
//in case: 1->1
if(fst.next!=cur)
prev.next=cur;
//ensure
return fake.next;
}
}
也可以写成双指针,因为fst=prev.next:
public class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        //require
        if(head==null)
            return head;
        ListNode fake=new ListNode(-1);
        fake.next=head;head=fake;
        //invariant
        ListNode prev=head,cur=prev.next;
        while(cur!=null){
            if(cur.val!=prev.next.val){
                if(prev.next.next!=cur)
                    prev.next=cur;
                else
                    prev=prev.next;
            }
            cur=cur.next;
        }
        if(prev.next.next!=cur)
            prev.next=cur;
        //ensure
        return fake.next;
    }
}                










