Skip to content

Commit ee5b9bd

Browse files
authored
feat: add solutions for lc No.2032 (#5175)
1 parent e1e1aec commit ee5b9bd

10 files changed

Lines changed: 452 additions & 96 deletions

File tree

solution/2000-2099/2032.Two Out of Three/README.md

Lines changed: 171 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -159,54 +159,49 @@ func twoOutOfThree(nums1 []int, nums2 []int, nums3 []int) (ans []int) {
159159

160160
```ts
161161
function twoOutOfThree(nums1: number[], nums2: number[], nums3: number[]): number[] {
162-
const count = new Array(101).fill(0);
163-
new Set(nums1).forEach(v => count[v]++);
164-
new Set(nums2).forEach(v => count[v]++);
165-
new Set(nums3).forEach(v => count[v]++);
166-
const ans = [];
167-
count.forEach((v, i) => {
168-
if (v >= 2) {
162+
const get = (nums: number[]): number[] => {
163+
const s = new Array(101).fill(0);
164+
for (const v of nums) {
165+
s[v] = 1;
166+
}
167+
return s;
168+
};
169+
170+
const s1 = get(nums1), s2 = get(nums2), s3 = get(nums3);
171+
const ans: number[] = [];
172+
173+
for (let i = 1; i <= 100; i++) {
174+
if (s1[i] + s2[i] + s3[i] > 1) {
169175
ans.push(i);
170176
}
171-
});
177+
}
172178
return ans;
173-
}
179+
};
174180
```
175181

176182
#### Rust
177183

178184
```rust
179-
use std::collections::HashSet;
180185
impl Solution {
181186
pub fn two_out_of_three(nums1: Vec<i32>, nums2: Vec<i32>, nums3: Vec<i32>) -> Vec<i32> {
182-
let mut count = vec![0; 101];
183-
nums1
184-
.into_iter()
185-
.collect::<HashSet<i32>>()
186-
.iter()
187-
.for_each(|&v| {
188-
count[v as usize] += 1;
189-
});
190-
nums2
191-
.into_iter()
192-
.collect::<HashSet<i32>>()
193-
.iter()
194-
.for_each(|&v| {
195-
count[v as usize] += 1;
196-
});
197-
nums3
198-
.into_iter()
199-
.collect::<HashSet<i32>>()
200-
.iter()
201-
.for_each(|&v| {
202-
count[v as usize] += 1;
203-
});
187+
let get = |nums: Vec<i32>| -> [i32; 101] {
188+
let mut s = [0; 101];
189+
for v in nums {
190+
s[v as usize] = 1;
191+
}
192+
s
193+
};
194+
195+
let s1 = get(nums1);
196+
let s2 = get(nums2);
197+
let s3 = get(nums3);
204198
let mut ans = Vec::new();
205-
count.iter().enumerate().for_each(|(i, v)| {
206-
if *v >= 2 {
199+
200+
for i in 1..=100 {
201+
if s1[i] + s2[i] + s3[i] > 1 {
207202
ans.push(i as i32);
208203
}
209-
});
204+
}
210205
ans
211206
}
212207
}
@@ -216,4 +211,145 @@ impl Solution {
216211

217212
<!-- solution:end -->
218213

214+
<!-- solution:start -->
215+
216+
### 方法二:哈希表 + 位运算
217+
218+
我们可以用一个哈希表 $\textit{mask}$ 来记录每个数在哪些数组中出现过。对于每个数组,我们将其中的元素加入哈希表中,并将对应的位设置为 $1$。例如,如果是第一个数组,则将对应的位设置为 $1$;如果是第二个数组,则将对应的位设置为 $2$;如果是第三个数组,则将对应的位设置为 $4$。
219+
220+
最后,我们枚举哈希表中的每个数,判断其对应的值对应的二进制位中是否至少有两位为 $1$,如果是,则将该数加入答案数组中。
221+
222+
时间复杂度 $O(n_1 + n_2 + n_3)$,空间复杂度 $O(n_1 + n_2 + n_3)$。其中 $n_1, n_2, n_3$ 分别为数组 $\textit{nums1}$, $\textit{nums2}$ 和 $\textit{nums3}$ 的长度。
223+
224+
<!-- tabs:start -->
225+
226+
#### Python3
227+
228+
```python
229+
class Solution:
230+
def twoOutOfThree(
231+
self, nums1: List[int], nums2: List[int], nums3: List[int]
232+
) -> List[int]:
233+
mask = defaultdict(int)
234+
for i, nums in enumerate((nums1, nums2, nums3)):
235+
for x in nums:
236+
mask[x] |= 1 << i
237+
return [x for x, v in mask.items() if v & (v - 1)]
238+
```
239+
240+
#### Java
241+
242+
```java
243+
class Solution {
244+
public List<Integer> twoOutOfThree(int[] nums1, int[] nums2, int[] nums3) {
245+
Map<Integer, Integer> mask = new HashMap<>();
246+
int[][] nums = {nums1, nums2, nums3};
247+
for (int i = 0; i < 3; i++) {
248+
for (int x : nums[i]) {
249+
mask.merge(x, 1 << i, (oldVal, newVal) -> oldVal | newVal);
250+
}
251+
}
252+
List<Integer> ans = new ArrayList<>();
253+
for (var e : mask.entrySet()) {
254+
if ((e.getValue() & (e.getValue() - 1)) != 0) {
255+
ans.add(e.getKey());
256+
}
257+
}
258+
return ans;
259+
}
260+
}
261+
```
262+
263+
#### C++
264+
265+
```cpp
266+
class Solution {
267+
public:
268+
vector<int> twoOutOfThree(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3) {
269+
unordered_map<int, int> mask;
270+
vector<vector<int>*> all = {&nums1, &nums2, &nums3};
271+
272+
for (int i = 0; i < 3; ++i) {
273+
for (int x : *all[i]) {
274+
mask[x] |= (1 << i);
275+
}
276+
}
277+
278+
vector<int> ans;
279+
for (auto& [x, m] : mask) {
280+
if (m & (m - 1)) {
281+
ans.push_back(x);
282+
}
283+
}
284+
return ans;
285+
}
286+
};
287+
```
288+
289+
#### Go
290+
291+
```go
292+
func twoOutOfThree(nums1 []int, nums2 []int, nums3 []int) (ans []int) {
293+
mask := make(map[int]int)
294+
for i, nums := range [][]int{nums1, nums2, nums3} {
295+
for _, x := range nums {
296+
mask[x] |= 1 << i
297+
}
298+
}
299+
for x, m := range mask {
300+
if m&(m-1) != 0 {
301+
ans = append(ans, x)
302+
}
303+
}
304+
return
305+
}
306+
```
307+
308+
#### TypeScript
309+
310+
```ts
311+
function twoOutOfThree(nums1: number[], nums2: number[], nums3: number[]): number[] {
312+
const mask = new Map<number, number>();
313+
const all = [nums1, nums2, nums3];
314+
315+
all.forEach((nums, i) => {
316+
for (const x of nums) {
317+
mask.set(x, (mask.get(x) || 0) | (1 << i));
318+
}
319+
});
320+
321+
return Array.from(mask.entries())
322+
.filter(([_, m]) => (m & (m - 1)) !== 0)
323+
.map(([x, _]) => x);
324+
};
325+
```
326+
327+
#### Rust
328+
329+
```rust
330+
use std::collections::HashMap;
331+
332+
impl Solution {
333+
pub fn two_out_of_three(nums1: Vec<i32>, nums2: Vec<i32>, nums3: Vec<i32>) -> Vec<i32> {
334+
let mut mask = HashMap::new();
335+
let all = vec![nums1, nums2, nums3];
336+
337+
for (i, nums) in all.into_iter().enumerate() {
338+
for x in nums {
339+
*mask.entry(x).or_insert(0) |= 1 << i;
340+
}
341+
}
342+
343+
mask.into_iter()
344+
.filter(|&(_, m)| m & (m - 1) != 0)
345+
.map(|(x, _)| x)
346+
.collect()
347+
}
348+
}
349+
```
350+
351+
<!-- tabs:end -->
352+
353+
<!-- solution:end -->
354+
219355
<!-- problem:end -->

0 commit comments

Comments
 (0)