[LeetCode]Remove Duplicates from Sorted List II

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的情况进行处理

【注意】

  1. 这个方法对head=null的情况不能处理,所以有12-13行的处理
  2. 29-30行是为了对例如:1->1这种情况进行处理。
  3. 返回是 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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值