[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

Constraints:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^8
  • 1 <= value <= 10^8
  • At most 50000 calls will be made to showFirstUnique and add.

第一个唯一数字。

题意是设计一个 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 题目总结

posted @ 2020-04-30 07:31  CNoodle  阅读(1484)  评论(0编辑  收藏  举报