• 【力扣】82. 删除排序链表中的重复元素 II


    存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。

    返回同样按升序排列的结果链表。

    示例 1:


    输入:head = [1,2,3,3,4,4,5]
    输出:[1,2,5]
    示例 2:


    输入:head = [1,1,1,2,3]
    输出:[2,3]
     

    提示:

    链表中节点数目在范围 [0, 300] 内
    -100 <= Node.val <= 100
    题目数据保证链表已经按升序排列

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    //假设使用额外的空间O(n),使用map记录每个节点的val出现的次数,达到一个统计的目的

    public ListNode deleteDuplicates(ListNode head) {
    
            //使用map key = 具体值,value = 出现的次数
            Map<Integer,Integer> map = new HashMap<>();
            ListNode current = head;
    
            while(current != null){
                map.put(current.val,map.getOrDefault(current.val,0)+1);
                current = current.next;
            }
    
            ListNode result = new ListNode();
            current = result;
            for(Map.Entry<Integer,Integer> entry : map.entrySet()){
                if(entry.getValue() == 1){
                    ListNode temp= new ListNode(entry.getKey());
                    current.next = temp;
                    current = current.next;
                }
            }
            return result.next;
        }

    结果测试用例是跑不通的了,原因很明显:最后使用map遍历,打乱了链表之前的顺序

    //那么就不再使用map遍历了,而是使用链表遍历

    public ListNode deleteDuplicates(ListNode head) {
    
            //使用map key = 具体值,value = 出现的次数
            Map<Integer,Integer> map = new HashMap<>();
            ListNode current = head;
    
            while(current != null){
                map.put(current.val,map.getOrDefault(current.val,0)+1);
                current = current.next;
            }
    
            ListNode result = new ListNode(0);
            current = result;
            while(head != null){
                if(map.get(head.val) == 1){
                    current.next = new ListNode(head.val);
                    current = current.next;
                }
                head = head.next;
            }
            return result.next;
        }

    这个当然测试用例是ok的,不过同样也存在问题,题目中明显的告诉我们是有序链表,我们这种方式并没有很好地应用到有序链表的特性,所以使用了额外的空间,目前时间复杂度为O(n) 空间复杂度为O(n)

    //那就再考虑下怎么不使用额外的空间

    其实也比较好想:

    public ListNode deleteDuplicates(ListNode head) {
    
            //这里您就问了,这是什么节点呢?
            //这是一个哑节点,没有存储数字的含义,作用就是:能够指向最终的结果。
            ListNode dummyNode = new ListNode(0);
            dummyNode.next = head;
    
            ListNode current = dummyNode;
    
            while(current.next != null && current.next.next != null){
    
                //如果说当前节点的下一个跟下一个的下一个值相等,则把下一个下一个都移除
                if(current.next.val == current.next.next.val){
    
                    //看到了吧,把当前值拿出来
                    int x = current.next.val;
    
                    //然后在这个循环里,删除current.next的值,如果等于x
                    while(current.next != null && current.next.val == x){
                        current.next = current.next.next;
                    }
                } else {
                    current = current.next;
                }
            }
    
            return dummyNode.next;
    
        }

    时间复杂度为O(n)、空间复杂度为O(1)

    一个入行不久的Java开发,越学习越感觉知识太多,自身了解太少,只能不断追寻
  • 相关阅读:
    Unique Paths II
    Subsets II
    Subsets
    Jump Game II
    Jump Game
    Valid Sudoku
    Valid Parentheses
    Length of Last Word
    Trapping Rain Water
    Sum Root to Leaf Numbers
  • 原文地址:https://www.cnblogs.com/fengtingxin/p/14703847.html
Copyright © 2020-2023  润新知