From 0e9204dfed64900f4f917da35b8106623a64758f Mon Sep 17 00:00:00 2001 From: Keisuke KUDO <151166401+Apo-Matchbox@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:41:22 +0900 Subject: [PATCH] Create 349. Intersection of Two Arrays.md --- 349/349. Intersection of Two Arrays.md | 140 +++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 349/349. Intersection of Two Arrays.md diff --git a/349/349. Intersection of Two Arrays.md b/349/349. Intersection of Two Arrays.md new file mode 100644 index 0000000..cd6f274 --- /dev/null +++ b/349/349. Intersection of Two Arrays.md @@ -0,0 +1,140 @@ +# [349. Intersection of Two Arrays](https://leetcode.com/problems/intersection-of-two-arrays/) +## Step1 +### 問題意図の考察 + - 問題文の確認 + 1. 2つの整数配列nums1, nums2 + 2. 両方の配列に共通して存在する要素のみを返して + 3. 結果の各要素は、重複なしであること + 4. 返す順番は任意で良い + + - 制約の確認 + 1. 1 <= nums1.length, nums2.length <= 1000 + 2. 0 <= nums1[i], nums2[i] <= 1000 + -> 1000 * 1000 最悪O(10^6) 100万 + -> unordered_set: O(n), ソート: O(n log n) + +### 解法を考える。 + - ハッシュセット?ソート?どっちがいいかな + - ソート O(n log n)/ ハッシュセット O(n)かな。 + - 問題を解いた後に、色々条件が追加される。その中で何がpros and consが挙げられるようにしたい + - 解法としては、nums1の要素を繰り返しハッシュセットに入れていく(重複しない) + - nums2も繰り返し入れていって、同じkeyを要素で返す + +初回の回答 +```cpp +#include +#include + +class Solution { + public: + std::vector intersection(std::vector& nums1, std::vector& nums2) { + std::unordered_set nums1_set; + for (int i = 0; i < nums1.size(); ++i) { + nums1_set.insert(nums1[i]); + } + + std::unordered_set result_set; + for (int i = 0; i < nums2.size(); ++i) { + if (nums1_set.find(nums2[i]) != nums1_set.end()) { + result_set.insert(nums2[i]); + } + } + + std::vector result; + for (std::unordered_set::iterator it = result_set.begin(); it != result_set.end(); ++it) { + result.push_back(*it); + } + return result; + } +}; + +``` + +## Step2 + - 改善点 + 1. loop内の整理 + 2. for文+set+vectorのみのシンプルな構造 + 3. 命名 result_set -> intersection_setへ nums2_setだと誤解が生まれる可能性がある + + - step1の修正 +```cpp +#include +#include + +class Solution { + public: + std::vector intersection(std::vector& nums1, std::vector& nums2) { + std::unordered_set nums1_set; + for (int i = 0; i < nums1.size(); ++i) { + nums1_set.insert(nums1[i]); + } + + std::unordered_set intersection_set; + for (int i = 0; i < nums2.size(); ++i) { + if (nums1_set.find(nums2[i]) != nums1_set.end()) { + intersection_set.insert(nums2[i]); + } + } + + std::vector result(intersection_set.begin(), intersection_set.end()); + return result; + } +}; + +``` + + - 他の方のコードを読む + * https://github.com/5ky7/arai60/pull/14/commits/5d8750fdca0c2c1e2bcc48a19be824450f931700 + +```cpp + set set_nums1(num1.begin(), num1.end()); +``` + +と書いた方がシンプル + + * https://github.com/5103246/LeetCode_Arai60/pull/13/commits/012aa0d6ed21bdb52c6dd416e2a8d8d76c4407ea + -> setとunordered_setここでは、そんなに誤差はないが、メモリオーバーヘッドが大きい、実装によってはcacheに乗りにくくて遅くなることもある。 + -> 解法の段階で思い込み。解法の時に手札を増やすこと。 + + - 全体的な修正(set) + +```cpp +#include +#include + +class Solution { + public: + std::vector intersection(std::vector& nums1, std::vector& nums2) { + std::set nums1_set(nums1.begin(), nums1.end()); + + std::set intersection_set; + for (int i = 0; i < nums2.size(); ++i) { + if (nums1_set.count(nums2[i])) { + intersection_set.insert(nums2[i]); + } + } + + std::vector result(intersection_set.begin(), intersection_set.end()); + return result; + } +}; + +``` + + - https://google.github.io/styleguide/cppguide.html#Performance + - https://en.cppreference.com/w/cpp/iterator.html + -> イテレータの振る舞い。挙動がよく分からなかった。もう一度確認必要。 + - https://en.cppreference.com/w/cpp/container/vector.html + - https://en.cppreference.com/w/cpp/container/set.html + - https://en.cppreference.com/w/cpp/container/unordered_set.html + -> vector/set/unordered_setの確認 + + - 他の解法 (ソート:時間がないので次回) + +## Step3 *自然な流れ(感覚に落とし込む) +1. 4min +2. 4min +3. 5min +4. 2min +5. 1min +