From 6f59d61b20d2444f57b964fef5c702c5218cd571 Mon Sep 17 00:00:00 2001 From: Hurukawa2121 Date: Sat, 21 Dec 2024 19:59:54 +0900 Subject: [PATCH 1/2] =?UTF-8?q?intersection-of-two-arrays=E3=81=AE?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 4.hash-map/intersection-of-two-arrays/memo.md | 32 +++++++++++++++++++ .../intersection-of-two-arrays/step1.cpp | 23 +++++++++++++ .../intersection-of-two-arrays/step2.cpp | 12 +++++++ .../intersection-of-two-arrays/step3.cpp | 12 +++++++ 4 files changed, 79 insertions(+) create mode 100644 4.hash-map/intersection-of-two-arrays/memo.md create mode 100644 4.hash-map/intersection-of-two-arrays/step1.cpp create mode 100644 4.hash-map/intersection-of-two-arrays/step2.cpp create mode 100644 4.hash-map/intersection-of-two-arrays/step3.cpp diff --git a/4.hash-map/intersection-of-two-arrays/memo.md b/4.hash-map/intersection-of-two-arrays/memo.md new file mode 100644 index 0000000..dd15296 --- /dev/null +++ b/4.hash-map/intersection-of-two-arrays/memo.md @@ -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 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分弱ほどで実装する。 diff --git a/4.hash-map/intersection-of-two-arrays/step1.cpp b/4.hash-map/intersection-of-two-arrays/step1.cpp new file mode 100644 index 0000000..d0b766f --- /dev/null +++ b/4.hash-map/intersection-of-two-arrays/step1.cpp @@ -0,0 +1,23 @@ +#include + +class Solution { +public: + std::vector intersection(std::vector& nums1, std::vector& nums2) { + std::unordered_set seen_in_nums1; + std::unordered_set seen_in_nums2; + for (int num : nums1) { + seen_in_nums1.insert(num); + } + std::vector 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; + } +}; diff --git a/4.hash-map/intersection-of-two-arrays/step2.cpp b/4.hash-map/intersection-of-two-arrays/step2.cpp new file mode 100644 index 0000000..1281434 --- /dev/null +++ b/4.hash-map/intersection-of-two-arrays/step2.cpp @@ -0,0 +1,12 @@ +#include + +class Solution { +public: + std::vector intersection(std::vector& nums1, std::vector& nums2) { + std::set unique_nums1(nums1.begin(), nums1.end()); + std::set unique_nums2(nums2.begin(), nums2.end()); + std::vector intersected_nums; + std::set_intersection(unique_nums1.begin(), unique_nums1.end(), unique_nums2.begin(), unique_nums2.end(), back_inserter(intersected_nums)); + return intersected_nums; + } +}; diff --git a/4.hash-map/intersection-of-two-arrays/step3.cpp b/4.hash-map/intersection-of-two-arrays/step3.cpp new file mode 100644 index 0000000..aba20e4 --- /dev/null +++ b/4.hash-map/intersection-of-two-arrays/step3.cpp @@ -0,0 +1,12 @@ +#include + +class Solution { +public: + std::vector intersection(std::vector& nums1, std::vector& nums2) { + std::set unique_nums1 = std::set(nums1.begin(), nums1.end()); + std::set unique_nums2 = std::set(nums2.begin(), nums2.end()); + std::vector 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; + } +}; From 5938a8d4544e5220d5a645b092b4eeabc58a51b7 Mon Sep 17 00:00:00 2001 From: Hurukawa2121 Date: Sat, 21 Dec 2024 20:03:50 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E8=A9=A6=E8=A1=8C=E9=8C=AF=E8=AA=A4?= =?UTF-8?q?=E3=81=A7=E6=8F=90=E5=87=BA=E3=82=B3=E3=83=BC=E3=83=89=E3=81=A8?= =?UTF-8?q?=E9=BD=9F=E9=BD=AC=E3=81=8C=E3=81=82=E3=81=A3=E3=81=9F=E3=81=9F?= =?UTF-8?q?=E3=82=81=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 4.hash-map/intersection-of-two-arrays/step1.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/4.hash-map/intersection-of-two-arrays/step1.cpp b/4.hash-map/intersection-of-two-arrays/step1.cpp index d0b766f..bb2bb64 100644 --- a/4.hash-map/intersection-of-two-arrays/step1.cpp +++ b/4.hash-map/intersection-of-two-arrays/step1.cpp @@ -1,10 +1,10 @@ -#include +#include class Solution { public: std::vector intersection(std::vector& nums1, std::vector& nums2) { - std::unordered_set seen_in_nums1; - std::unordered_set seen_in_nums2; + std::set seen_in_nums1; + std::set seen_in_nums2; for (int num : nums1) { seen_in_nums1.insert(num); }