两种方案删除排序链表中的重复元素

本文介绍了两种方法解决LeetCode中的删除排序链表重复元素问题:一是使用数组记录节点值出现次数并分两遍处理,二是利用链表有序特性进行一次遍历删除。讲解了如何通过偏移量和计数数组简化问题,并展示了两种高效解决方案的代码实现。
摘要由CSDN通过智能技术生成

删除排序链表中的重复元素

力扣题目链接 -> 传送门
所用语言:Java
第一种方法是用了两次遍历,运行用时1ms,内存消耗37MB左右
第二种方法是用了一次遍历,运行用时0ms,内存消耗37MB左右


正文

解析①

可以看到,在题目的提示中结点值的范围是[-100, 100],这个范围并不是很大,我们可以使用数组来记录每个值出现的次数。

例如:我们定义一个偏移量int offset = 100,使用偏移量将结点值的范围控制在[0, 200]之内。然后我们就可以定义一个记录数组int count[] = new int[201],数组的下标val + offset表示结点值val,而count[val + offset]则表示值val出现过的次数。如果count[val + offset] > 1,表示值为val的结点是重复结点,需要删除掉。

使用上面这种思路,我们一共需要两趟遍历。第一趟遍历用来填充记录数组count;第二趟遍历用来删除重复结点。

另外,在第二趟遍历时,因为题目要求要保留重复结点中的一个,所以在删除结点的同时也要对count[val + offset]减一,以改变重复结点的个数。当其个数等于1时,停止对该值结点的删减。

Tip: 这是一种典型的,将数值定义转化为另一种定义,方便问题的求解。**另外,这种方法不仅仅适用于有序链表,更适用于在无序链表中删除重复结点。

解析②

利用链表是有序的这个特点:如果值为n的结点有重复,那么重复结点是它的下一个结点。
所以,当遇到重复结点时,我们只需要一个一个地进行删除好了(基操)。详情请看答案②

答案①

public ListNode deleteDuplicates(ListNode head) {
        if (head == null) {
            return head;
        }

        int count[] = new int[201];
        int offset = 100;
        ListNode list = head;

        do {
            count[list.val + offset]++;
            list = list.next;
        } while (list != null);

        list = head;
        while (list.next != null) {
            if (count[list.next.val + offset] > 1) {
                // 注意: count[list.next.val + offset]-- 和 list.next = list.next.next 的顺序不能颠倒
                count[list.next.val + offset]--;
                list.next = list.next.next;
            } else {
                list = list.next;
            }
        }

        // 处理头结点
        if (count[head.val + offset] > 1) {
            head = head.next;
        }
        return head;
    }

答案②

public ListNode deleteDuplicates(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }

        ListNode tail = new ListNode();
        ListNode list = tail;
        while (head.next != null) {
            if (head.val != head.next.val) {
                tail.next = head;
                tail = head;
                head = head.next;
            } else {
                // 跳过相同值的结点,但是head依旧停留在原处
                head.next = head.next.next;
            }
        }

        tail.next = head;
        return list.next;
    }

最后

简单题,考察链表的操作而已
删除排序链表中的重复元素II 请看 -> 传送门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值