Skip to content

Commit 6f59d61

Browse files
committed
intersection-of-two-arraysの実装
1 parent d70dfa9 commit 6f59d61

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## step1
2+
- `map` でもいいが value を使わないので `std::set``std::unordered_set` を採用する。
3+
4+
- `std::set``std::unordered_set` のどちらを使う考える。
5+
- `std::unordered_set` はハッシュテーブルなので整数徐算が遅いCPUアーキテクチャ (ARMなど) では遅くなる可能性がある。数回比較する (`std::set` を使う) 方が早い可能性がある。
6+
- https://chromium.googlesource.com/chromium/src/+/master/base/containers/README.md#std_unordered_map-and-std_unordered_set
7+
- `std::unordered_set`も C++11 からリハッシュできるようだが、最悪の場合で 計算量に`std::unordered_set::size` の二乗かかるので、(確率に依るが) あまり使いたくない。
8+
- https://cpprefjp.github.io/reference/unordered_set/unordered_set/rehash.html
9+
- `std::set` の方が良いと考える。
10+
11+
## step2
12+
- 他のコードを見る
13+
14+
- 以下の初期化方法が C++17 からあった。
15+
```cpp
16+
std::unordered_set<int> unique_nums1(nums1.begin(), nums1.end());
17+
```
18+
- これなら `seen_in_nums1` より `unique_nums1` の方が自然。
19+
20+
- C++03 から `std::set_intersection` がある。
21+
- `std::unordered_set` だと Wrong Answer になる。
22+
- ソートしていない場合は未定義動作とある。(つまり何が起きても構わない。)
23+
- https://en.cppreference.com/w/cpp/algorithm/set_intersection#:~:text=range%2C%20preserving%20order.-,1),-If
24+
25+
- C++03 からの `std::back_inserter` をOutputIterator で使う。
26+
- https://en.cppreference.com/w/cpp/iterator/back_inserter
27+
- つまり `*(back_inserter(vec)) = value;` で `vec.push_back(value);` になる。
28+
- 今回と関係ないが、他の書き込みを想定したイテレータを初めて知る。
29+
- https://stackoverflow.com/questions/19907677/whats-the-difference-between-iterator-and-back-insert-iterator#:~:text=see%20the%20following-,(adaptor)%20iterators,-%3A
30+
31+
## step3
32+
- 補完無しで2分弱ほどで実装する。
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <unordered_set>
2+
3+
class Solution {
4+
public:
5+
std::vector<int> intersection(std::vector<int>& nums1, std::vector<int>& nums2) {
6+
std::unordered_set<int> seen_in_nums1;
7+
std::unordered_set<int> seen_in_nums2;
8+
for (int num : nums1) {
9+
seen_in_nums1.insert(num);
10+
}
11+
std::vector<int> intersected_nums;
12+
for (int num : nums2) {
13+
if (seen_in_nums2.contains(num)) {
14+
continue;
15+
}
16+
if (seen_in_nums1.contains(num)) {
17+
intersected_nums.push_back(num);
18+
seen_in_nums2.insert(num);
19+
}
20+
}
21+
return intersected_nums;
22+
}
23+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <set>
2+
3+
class Solution {
4+
public:
5+
std::vector<int> intersection(std::vector<int>& nums1, std::vector<int>& nums2) {
6+
std::set<int> unique_nums1(nums1.begin(), nums1.end());
7+
std::set<int> unique_nums2(nums2.begin(), nums2.end());
8+
std::vector<int> intersected_nums;
9+
std::set_intersection(unique_nums1.begin(), unique_nums1.end(), unique_nums2.begin(), unique_nums2.end(), back_inserter(intersected_nums));
10+
return intersected_nums;
11+
}
12+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <set>
2+
3+
class Solution {
4+
public:
5+
std::vector<int> intersection(std::vector<int>& nums1, std::vector<int>& nums2) {
6+
std::set<int> unique_nums1 = std::set(nums1.begin(), nums1.end());
7+
std::set<int> unique_nums2 = std::set(nums2.begin(), nums2.end());
8+
std::vector<int> intersected_nums;
9+
std::set_intersection(unique_nums1.begin(), unique_nums1.end(), unique_nums2.begin(), unique_nums2.end(), std::back_inserter(intersected_nums));
10+
return intersected_nums;
11+
}
12+
};

0 commit comments

Comments
 (0)