• [LeetCode] 1429. First Unique Number


    You have a queue of integers, you need to retrieve the first unique integer in the queue.

    Implement the FirstUnique class:

    • FirstUnique(int[] nums) Initializes the object with the numbers in the queue.
    • int showFirstUnique() returns the value of the first unique integer of the queue, and returns -1 if there is no such integer.
    • void add(int value) insert value to the queue.

    Example 1:

    Input: 
    ["FirstUnique","showFirstUnique","add","showFirstUnique","add","showFirstUnique","add","showFirstUnique"]
    [[[2,3,5]],[],[5],[],[2],[],[3],[]]
    Output: 
    [null,2,null,2,null,3,null,-1]
    
    Explanation: 
    FirstUnique firstUnique = new FirstUnique([2,3,5]);
    firstUnique.showFirstUnique(); // return 2
    firstUnique.add(5);            // the queue is now [2,3,5,5]
    firstUnique.showFirstUnique(); // return 2
    firstUnique.add(2);            // the queue is now [2,3,5,5,2]
    firstUnique.showFirstUnique(); // return 3
    firstUnique.add(3);            // the queue is now [2,3,5,5,2,3]
    firstUnique.showFirstUnique(); // return -1
    
    

    Example 2:

    Input: 
    ["FirstUnique","showFirstUnique","add","add","add","add","add","showFirstUnique"]
    [[[7,7,7,7,7,7]],[],[7],[3],[3],[7],[17],[]]
    Output: 
    [null,-1,null,null,null,null,null,17]
    
    Explanation: 
    FirstUnique firstUnique = new FirstUnique([7,7,7,7,7,7]);
    firstUnique.showFirstUnique(); // return -1
    firstUnique.add(7);            // the queue is now [7,7,7,7,7,7,7]
    firstUnique.add(3);            // the queue is now [7,7,7,7,7,7,7,3]
    firstUnique.add(3);            // the queue is now [7,7,7,7,7,7,7,3,3]
    firstUnique.add(7);            // the queue is now [7,7,7,7,7,7,7,3,3,7]
    firstUnique.add(17);           // the queue is now [7,7,7,7,7,7,7,3,3,7,17]
    firstUnique.showFirstUnique(); // return 17
    
    

    Example 3:

    Input: 
    ["FirstUnique","showFirstUnique","add","showFirstUnique"]
    [[[809]],[],[809],[]]
    Output: 
    [null,809,null,-1]
    
    Explanation: 
    FirstUnique firstUnique = new FirstUnique([809]);
    firstUnique.showFirstUnique(); // return 809
    firstUnique.add(809);          // the queue is now [809,809]
    firstUnique.showFirstUnique(); // return -1

    题意是设计一个FirstUnique的class,包含一开始列出的三个函数。可以发现,因为没有删除操作,加入queue的数字从未被拿出来,但是每次需要返回的是第一个unique的数字。既然是找unique的数字,必然会牵涉到hashmap,所以我的思路是用一个hashmap记录每个数字及其他们各自的出现次数,同时创建一个queue,在做add操作的时候也是无条件将元素加入queue。但是在showFirstUnique中,如果queue里面头一个节点(peek)不是unique的,则弹出这个元素,直到找到一个unique的元素。这个思路可行但是时间复杂度不太理想。

    时间O(n) - 有可能queue需要弹出很多元素之后才能找的到第一个unique value

    空间O(n)

    Java实现

     1 class FirstUnique {
     2     HashMap<Integer, Integer> map;
     3     Queue<Integer> queue;
     4     
     5     public FirstUnique(int[] nums) {
     6         map = new HashMap<>();
     7         queue = new LinkedList<>();
     8         for (int num : nums) {
     9             add(num);
    10         }
    11     }
    12     
    13     public int showFirstUnique() {
    14         while (!queue.isEmpty()) {
    15             int num = queue.peek();
    16             int freq = map.get(num);
    17             if (freq > 1) {
    18                 queue.poll();
    19             } else {
    20                 return num;
    21             }
    22         }
    23         return -1;
    24     }
    25     
    26     public void add(int value) {
    27         if (map.containsKey(value)) {
    28             map.put(value, map.get(value) + 1);
    29         } else {
    30             map.put(value, 1);
    31             queue.add(value);
    32         }
    33     }
    34 }
    35 
    36 /**
    37  * Your FirstUnique object will be instantiated and called as such:
    38  * FirstUnique obj = new FirstUnique(nums);
    39  * int param_1 = obj.showFirstUnique();
    40  * obj.add(value);
    41  */

    网上看到一个更好的解法,思路差不多,但是用到了LinkedHashSet帮助记录unique value。思路是用一个hashset和一个LinkedHashSet记录元素,hashset首先还是在记录独一的元素,当遍历到重复元素后,hashset也只会返回false;LinkedHashSet因为是有序的,所以当遍历到重复元素的时候,需要把这个元素从LinkedHashSet中删去。这样在返回unique value的时候,时间上会省很多。

    时间O(n),虽然返回unique的动作是O(1)但是add()函数在极端情况下也会很费时间

    空间O(n)

    Java实现

     1 class FirstUnique {
     2     Set<Integer> unique = new LinkedHashSet<>();
     3     Set<Integer> all = new HashSet<>();
     4     
     5     public FirstUnique(int[] nums) {
     6         for (int num : nums) {
     7             add(num);
     8         }
     9     }
    10     
    11     public int showFirstUnique() {
    12         if (unique.isEmpty()) {
    13             return -1;
    14         }
    15         return unique.iterator().next();
    16     }
    17     
    18     public void add(int value) {
    19         if (all.add(value)) {
    20             unique.add(value);
    21         } else {
    22             unique.remove(value);
    23         }
    24     }
    25 }
    26 
    27 /**
    28  * Your FirstUnique object will be instantiated and called as such:
    29  * FirstUnique obj = new FirstUnique(nums);
    30  * int param_1 = obj.showFirstUnique();
    31  * obj.add(value);
    32  */

    LeetCode 题目总结

  • 相关阅读:
    围炉夜话(3)
    围炉夜话(2)
    一步步学习SPD2010--第十一章节--处理母版页(9)--导出母版页
    一步步学习SPD2010--第十一章节--处理母版页(8)--从母版页创建网页
    一步步学习SPD2010--第十一章节--处理母版页(7)--管理Content Placeholders
    一步步学习SPD2010--第十一章节--处理母版页(6)--改变默认母版页
    一步步学习SPD2010--第十一章节--处理母版页(5)--自定义母版页
    一步步学习SPD2010--第十一章节--处理母版页(4)--复制和保存母版页
    一步步学习SPD2010--第十一章节--处理母版页(3)--母版页上使用的控件
    如何使用外部数据列创建SP列表
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12806522.html
Copyright © 2020-2023  润新知