Skip to content

Commit eb340e0

Browse files
committed
feat: add solutions to lc problem: No.1429
No.1429.First Unique Number
1 parent 6e074dc commit eb340e0

File tree

9 files changed

+419
-128
lines changed

9 files changed

+419
-128
lines changed

solution/1400-1499/1429.First Unique Number/README.md

+159-34
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,15 @@ firstUnique.showFirstUnique(); // 返回 -1
8686

8787
<!-- 这里可写通用的实现逻辑 -->
8888

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$ 的长度。
9098

9199
<!-- tabs:start -->
92100

@@ -96,29 +104,42 @@ firstUnique.showFirstUnique(); // 返回 -1
96104

97105
```python
98106
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+
99131
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)
107134

108135
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]
113139

114140
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)
122143

123144

124145
# Your FirstUnique object will be instantiated and called as such:
@@ -133,35 +154,65 @@ class FirstUnique:
133154

134155
```java
135156
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<>();
138159

139160
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);
144163
}
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);
148167
}
149168
}
150169
}
151170

152171
public int showFirstUnique() {
153-
return uniqueNums.isEmpty() ? -1 : uniqueNums.iterator().next();
172+
return unique.isEmpty() ? -1 : unique.iterator().next();
154173
}
155174

156175
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);
160179
} 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);
163202
}
164203
}
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+
}
165216
}
166217

167218
/**
@@ -172,6 +223,80 @@ class FirstUnique {
172223
*/
173224
```
174225

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+
175300
### **...**
176301

177302
```

0 commit comments

Comments
 (0)