剑指Offer-删除排好序的单链表中的重复节点

12.删除排好序的单链表中的重复节点

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留。

样例1
输入:1->2->3->3->4->4->5

输出:1->2->5
样例2
输入:1->1->1->2->3

输出:2->3

思路

此题需要注意的有两点:

  • 头结点的删除。比如样例2中怎么把1删了?
  • 重复节点不能保留。

所以如果按照一般的删除节点思路,无法满足以上两点。此时我们需要一个虚拟头结点来充当“前一个节点”。在返回时再把它去掉即可。链表的题目一定要注意空指针异常!

class Solution {
    public ListNode deleteDuplication(ListNode head) {
        if(head==null||head.next==null)
                return head;
            //创建虚拟头结点(Virtual Head)
            ListNode vHead = new ListNode(-1);
            vHead.next = head;
            ListNode p = vHead;
            ListNode q = p.next;
        	//注意这里的判空条件,实际上,每次删除完节点,p与q都是前后节点的关系
        	//所以我们只需要判断p.next不为null作为大的判空条件,q!=null是小的判空条件
        	//因为q是走在前面的
            while (p.next!=null) {
                while (q!=null && p.next.val == q.val) q = q.next;
                //案例1的情况,p根本没动,无需删除头结点
                if ( p.next.next == q) p = p.next;
                //如果是案例2的情况,需要删除头结点
                else p.next = q;
            }
            return vHead.next;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值