@@ -86,7 +86,15 @@ firstUnique.showFirstUnique(); // 返回 -1
86
86
87
87
<!-- 这里可写通用的实现逻辑 -->
88
88
89
- “有序哈希表”实现。
89
+ ** 方法一:哈希表 + 双端队列**
90
+
91
+ 我们可以使用哈希表 $cnt$ 统计每个数字出现的次数,使用双端队列 $q$ 按顺序维护出现的数字。
92
+
93
+ 调用 ` showFirstUnique ` 方法时,判断队列 $q$ 的队头元素是否在哈希表 $cnt$ 中出现的次数是否为 $1$,如果是,则返回队头元素,否则将队头元素弹出,直到队列为空或者队头元素在哈希表 $cnt$ 中出现的次数为 $1$,如果队列为空,则返回 $-1$。
94
+
95
+ 调用 ` add ` 方法时,将数字加入哈希表 $cnt$ 中,并将数字加入队列 $q$ 中。
96
+
97
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
90
98
91
99
<!-- tabs:start -->
92
100
@@ -96,29 +104,42 @@ firstUnique.showFirstUnique(); // 返回 -1
96
104
97
105
``` python
98
106
class FirstUnique :
107
+
108
+ def __init__ (self , nums : List[int ]):
109
+ self .cnt = Counter(nums)
110
+ self .unique = OrderedDict({v: 1 for v in nums if self .cnt[v] == 1 })
111
+
112
+ def showFirstUnique (self ) -> int :
113
+ return - 1 if not self .unique else next (v for v in self .unique.keys())
114
+
115
+ def add (self , value : int ) -> None :
116
+ self .cnt[value] += 1
117
+ if self .cnt[value] == 1 :
118
+ self .unique[value] = 1
119
+ elif value in self .unique:
120
+ self .unique.pop(value)
121
+
122
+ # Your FirstUnique object will be instantiated and called as such:
123
+ # obj = FirstUnique(nums)
124
+ # param_1 = obj.showFirstUnique()
125
+ # obj.add(value)
126
+ ```
127
+
128
+ ``` python
129
+ class FirstUnique :
130
+
99
131
def __init__ (self , nums : List[int ]):
100
- self .counter = OrderedDict()
101
- self .unique_nums = OrderedDict()
102
- for num in nums:
103
- self .counter[num] = self .counter.get(num, 0 ) + 1
104
- for k, v in self .counter.items():
105
- if v == 1 :
106
- self .unique_nums[k] = 1
132
+ self .cnt = Counter(nums)
133
+ self .q = deque(nums)
107
134
108
135
def showFirstUnique (self ) -> int :
109
- if len (self .unique_nums) == 0 :
110
- return - 1
111
- for k in self .unique_nums.keys():
112
- return k
136
+ while self .q and self .cnt[self .q[0 ]] != 1 :
137
+ self .q.popleft()
138
+ return - 1 if not self .q else self .q[0 ]
113
139
114
140
def add (self , value : int ) -> None :
115
- if value not in self .counter:
116
- self .counter[value] = 1
117
- self .unique_nums[value] = 1
118
- else :
119
- self .counter[value] += 1
120
- if value in self .unique_nums:
121
- self .unique_nums.pop(value)
141
+ self .cnt[value] += 1
142
+ self .q.append(value)
122
143
123
144
124
145
# Your FirstUnique object will be instantiated and called as such:
@@ -133,35 +154,65 @@ class FirstUnique:
133
154
134
155
``` java
135
156
class FirstUnique {
136
- private Map<Integer , Integer > counter ;
137
- private Set<Integer > uniqueNums ;
157
+ private Map<Integer , Integer > cnt = new HashMap<> () ;
158
+ private Set<Integer > unique = new LinkedHashSet<> () ;
138
159
139
160
public FirstUnique (int [] nums ) {
140
- counter = new LinkedHashMap<> ();
141
- uniqueNums = new LinkedHashSet<> ();
142
- for (int num : nums) {
143
- counter. put(num, counter. getOrDefault(num, 0 ) + 1 );
161
+ for (int v : nums) {
162
+ cnt. put(v, cnt. getOrDefault(v, 0 ) + 1 );
144
163
}
145
- for (Map . Entry< Integer , Integer > entry : counter . entrySet() ) {
146
- if (entry . getValue( ) == 1 ) {
147
- uniqueNums . add(entry . getKey() );
164
+ for (int v : nums ) {
165
+ if (cnt . get(v ) == 1 ) {
166
+ unique . add(v );
148
167
}
149
168
}
150
169
}
151
170
152
171
public int showFirstUnique () {
153
- return uniqueNums . isEmpty() ? - 1 : uniqueNums . iterator(). next();
172
+ return unique . isEmpty() ? - 1 : unique . iterator(). next();
154
173
}
155
174
156
175
public void add (int value ) {
157
- if ( ! counter . containsKey (value)) {
158
- counter . put (value, 1 );
159
- uniqueNums . add(value);
176
+ cnt . put(value, cnt . getOrDefault (value, 0 ) + 1 );
177
+ if (cnt . get (value) == 1 ) {
178
+ unique . add(value);
160
179
} else {
161
- counter. put(value, counter. get(value) + 1 );
162
- uniqueNums. remove(value);
180
+ unique. remove(value);
181
+ }
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Your FirstUnique object will be instantiated and called as such:
187
+ * FirstUnique obj = new FirstUnique(nums);
188
+ * int param_1 = obj.showFirstUnique();
189
+ * obj.add(value);
190
+ */
191
+ ```
192
+
193
+ ``` java
194
+ class FirstUnique {
195
+ private Map<Integer , Integer > cnt = new HashMap<> ();
196
+ private Deque<Integer > q = new ArrayDeque<> ();
197
+
198
+ public FirstUnique (int [] nums ) {
199
+ for (int v : nums) {
200
+ cnt. put(v, cnt. getOrDefault(v, 0 ) + 1 );
201
+ q. offer(v);
163
202
}
164
203
}
204
+
205
+ public int showFirstUnique () {
206
+ while (! q. isEmpty() && cnt. get(q. peekFirst()) != 1 ) {
207
+ q. poll();
208
+ }
209
+ return q. isEmpty() ? - 1 : q. peekFirst();
210
+ }
211
+
212
+ public void add (int value ) {
213
+ cnt. put(value, cnt. getOrDefault(value, 0 ) + 1 );
214
+ q. offer(value);
215
+ }
165
216
}
166
217
167
218
/**
@@ -172,6 +223,80 @@ class FirstUnique {
172
223
*/
173
224
```
174
225
226
+ ### ** C++**
227
+
228
+ ``` cpp
229
+ class FirstUnique {
230
+ public:
231
+ FirstUnique(vector<int >& nums) {
232
+ for (int& v : nums) {
233
+ ++cnt[ v] ;
234
+ q.push_back(v);
235
+ }
236
+ }
237
+
238
+ int showFirstUnique() {
239
+ while (q.size() && cnt[q.front()] != 1) q.pop_front();
240
+ return q.size() ? q.front() : -1;
241
+ }
242
+
243
+ void add (int value) {
244
+ ++cnt[ value] ;
245
+ q.push_back(value);
246
+ }
247
+
248
+ private:
249
+ unordered_map<int, int> cnt;
250
+ deque<int > q;
251
+ };
252
+
253
+ /**
254
+ * Your FirstUnique object will be instantiated and called as such:
255
+ * FirstUnique* obj = new FirstUnique(nums);
256
+ * int param_1 = obj->showFirstUnique();
257
+ * obj->add(value);
258
+ * /
259
+ ```
260
+
261
+ ### **Go**
262
+
263
+ ```go
264
+ type FirstUnique struct {
265
+ cnt map[int]int
266
+ q []int
267
+ }
268
+
269
+ func Constructor(nums []int) FirstUnique {
270
+ cnt := map[int]int{}
271
+ for _, v := range nums {
272
+ cnt[v]++
273
+ }
274
+ return FirstUnique{cnt, nums}
275
+ }
276
+
277
+ func (this *FirstUnique) ShowFirstUnique() int {
278
+ for len(this.q) > 0 && this.cnt[this.q[0]] != 1 {
279
+ this.q = this.q[1:]
280
+ }
281
+ if len(this.q) > 0 {
282
+ return this.q[0]
283
+ }
284
+ return -1
285
+ }
286
+
287
+ func (this *FirstUnique) Add(value int) {
288
+ this.cnt[value]++
289
+ this.q = append(this.q, value)
290
+ }
291
+
292
+ /**
293
+ * Your FirstUnique object will be instantiated and called as such:
294
+ * obj := Constructor(nums);
295
+ * param_1 := obj.ShowFirstUnique();
296
+ * obj.Add(value);
297
+ */
298
+ ```
299
+
175
300
### ** ...**
176
301
177
302
```
0 commit comments