-
Notifications
You must be signed in to change notification settings - Fork 0
349. Intersection of Two Arrays #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
## step1 | ||
- `map` でもいいが value を使わないので `std::set` か `std::unordered_set` を採用する。 | ||
|
||
- `std::set` と `std::unordered_set` のどちらを使う考える。 | ||
- `std::unordered_set` はハッシュテーブルなので整数徐算が遅いCPUアーキテクチャ (ARMなど) では遅くなる可能性がある。数回比較する (`std::set` を使う) 方が早い可能性がある。 | ||
- https://chromium.googlesource.com/chromium/src/+/master/base/containers/README.md#std_unordered_map-and-std_unordered_set | ||
- `std::unordered_set`も C++11 からリハッシュできるようだが、最悪の場合で 計算量に`std::unordered_set::size` の二乗かかるので、(確率に依るが) あまり使いたくない。 | ||
- https://cpprefjp.github.io/reference/unordered_set/unordered_set/rehash.html | ||
- `std::set` の方が良いと考える。 | ||
|
||
## step2 | ||
- 他のコードを見る | ||
|
||
- 以下の初期化方法が C++17 からあった。 | ||
```cpp | ||
std::unordered_set<int> unique_nums1(nums1.begin(), nums1.end()); | ||
``` | ||
- これなら `seen_in_nums1` より `unique_nums1` の方が自然。 | ||
|
||
- C++03 から `std::set_intersection` がある。 | ||
- `std::unordered_set` だと Wrong Answer になる。 | ||
- ソートしていない場合は未定義動作とある。(つまり何が起きても構わない。) | ||
- https://en.cppreference.com/w/cpp/algorithm/set_intersection#:~:text=range%2C%20preserving%20order.-,1),-If | ||
|
||
- C++03 からの `std::back_inserter` をOutputIterator で使う。 | ||
- https://en.cppreference.com/w/cpp/iterator/back_inserter | ||
- つまり `*(back_inserter(vec)) = value;` で `vec.push_back(value);` になる。 | ||
- 今回と関係ないが、他の書き込みを想定したイテレータを初めて知る。 | ||
- https://stackoverflow.com/questions/19907677/whats-the-difference-between-iterator-and-back-insert-iterator#:~:text=see%20the%20following-,(adaptor)%20iterators,-%3A | ||
|
||
## step3 | ||
- 補完無しで2分弱ほどで実装する。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. このような議論もありました There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 共有していただきありがとうございます。 片方をソートする場合、引数をサイズが小さい配列と大きい配列に分け、小さい方をソートする方法を考えました。 確かに、条件を変えたときに案があまり出てきませんでした。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#include <set> | ||
|
||
class Solution { | ||
public: | ||
std::vector<int> intersection(std::vector<int>& nums1, std::vector<int>& nums2) { | ||
std::set<int> seen_in_nums1; | ||
std::set<int> seen_in_nums2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. この変数は There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
「最後にreturnするvectorへ追加済であること」の追加済を意味するaddedです。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
for (int num : nums1) { | ||
seen_in_nums1.insert(num); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. これ、コンストラクタでできませんでしたっけ。.begin(), .end() を渡すと。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. あ、下にありましたね。 |
||
} | ||
std::vector<int> intersected_nums; | ||
for (int num : nums2) { | ||
if (seen_in_nums2.contains(num)) { | ||
continue; | ||
} | ||
if (seen_in_nums1.contains(num)) { | ||
intersected_nums.push_back(num); | ||
seen_in_nums2.insert(num); | ||
} | ||
} | ||
return intersected_nums; | ||
} | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます。 何か良い変数名はありますでしょうか。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nums1_not_in_nums2 しか思いつかないですが、なんか不恰好ですね、、 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not_inの発想はなかったです。 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <set> | ||
|
||
class Solution { | ||
public: | ||
std::vector<int> intersection(std::vector<int>& nums1, std::vector<int>& nums2) { | ||
std::set<int> unique_nums1(nums1.begin(), nums1.end()); | ||
std::set<int> unique_nums2(nums2.begin(), nums2.end()); | ||
std::vector<int> intersected_nums; | ||
std::set_intersection(unique_nums1.begin(), unique_nums1.end(), unique_nums2.begin(), unique_nums2.end(), back_inserter(intersected_nums)); | ||
return intersected_nums; | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#include <set> | ||
|
||
class Solution { | ||
public: | ||
std::vector<int> intersection(std::vector<int>& nums1, std::vector<int>& nums2) { | ||
std::set<int> unique_nums1 = std::set(nums1.begin(), nums1.end()); | ||
std::set<int> unique_nums2 = std::set(nums2.begin(), nums2.end()); | ||
std::vector<int> intersected_nums; | ||
std::set_intersection(unique_nums1.begin(), unique_nums1.end(), unique_nums2.begin(), unique_nums2.end(), std::back_inserter(intersected_nums)); | ||
return intersected_nums; | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set_intersection の実装は見ておいてください。
マージソート的な書き方はなんとなく頭にあります。
メモリーに乗らないくらい巨大でも、ソートされているならば、両方から取り出して、小さい方を進めていき、同じだったらそれを確保するということです。
誰か書いていたと思いますね。
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ありがとうございます。
set_intersection の実装を見ました。
サイズが大きい方の配列の探索が対数時間で済むのですね。
こちらの議論は @hroc135 さんが教えてくださいました。