diff --git a/04_HashMap/1.Two_sum.md b/04_HashMap/1.Two_sum.md new file mode 100644 index 0000000..89cfffb --- /dev/null +++ b/04_HashMap/1.Two_sum.md @@ -0,0 +1,124 @@ +<問題> +https://leetcode.com/problems/two-sum/ + +# step1 + +5分程度答えを見ずに考えて、手が止まるまでやってみる。 +何も思いつかなければ、答えを見て解く。 +ただし、コードを書くときは答えを見ないこと。 +正解したら一旦OK。 +思考過程もメモしてみる。 + +```c++ +class Solution { +public: + vector twoSum(vector& nums, int target) { + for (int i = 0; i < nums.size() - 1; i++) { + for (int j = i + 1; j < nums.size(); j++) { + if (nums[i] + nums[j] == target) + return {i, j}; + } + } + return {}; + } +}; +``` + +【考えたこと】 +- 単純にnC2の組み合わせを全通り考える。 +- ソートしてから(O(nlogn))、値iに対して、target-iとなる整数をソート済みの配列にあるか調べる(O(nlogn))方法もありそう。 +- 探した要素が元々何番目の要素だったか記憶しておく必要がある。 +- 2分探索が必要となる。一度自分で書いてみる。 + +# step2 +他の方が描いたコードを見て、参考にしてコードを書き直してみる。 +参考にしたコードのリンクは貼っておく。 +読みやすいことを意識する。 +他の解法も考えみる。 + +計算量:O(N) + + +```c++ +class Solution { +public: + vector twoSum(vector& nums, int target) { + map num_to_indexes = {}; + for (int i = 0; i < size(nums); i++) { + int diffrence = target-nums[i]; + if (num_to_indexes.contains(diffrence)) { + return{i,num_to_indexes[diffrence]}; + } + num_to_indexes[nums[i]] = i; + } + return {}; + } +}; +``` + +例外処理もあると良い。 +ここでは、和がtargetとなる組み合わせがない時を想定。 +> プログラムの一貫性が重要で、期待する出力が必ずあるべきケースや、異常事態で処理を止めたい場合などは例外発生させる。 + +> 「公式ドキュメントに目を通す」という行動を取りたくなること自体が大事です。つまり、結果ではなくて欲求を評価しましょう。 +何を使うかではなくて、何は不適切であると感じたかも大事です。つまり、結果ではなくて過程を評価しましょう。 +最終的にはエンジニアリングという目的との関係から評価します。つまり、結果ではなくて目的を評価しましょう。 + +C++では例外処理はあまり使わないのか?? +一旦、答えがないときは空のペアを返すままとした。 +https://google.github.io/styleguide/cppguide.html#Exceptions + +mapを使って書いてみる。 +空のmapを作って、順番に入れていきペアがあるか知ればれば良い。 +keyが与えられた値、valがindex。 + +mapのcontains()では、keyがあるか探すだけなので、 +アクセスによる要素作成はないと認識している。 +https://en.cppreference.com/w/cpp/container/map/contains + +>今でなくて良いとは思いますが、余裕があればHash Tableの衝突回避のメカニズムも馴染みがなければ軽く目を通しておくと良いと思います。Open Addressing, Separete Chaining + + +mapは平衡2分木、問題の分類として +Hashになっているので、Hashを使った方法もあるはず。 +unordered_mapはハッシュデーブルで実装されているらしい。 +こちらも使ってよさそう。→ +https://cpprefjp.github.io/reference/unordered_map/unordered_map.html + +ちなみにsetは二分木 +https://cpprefjp.github.io/reference/set/set.html + +unorderedmapとmapの違い +https://qiita.com/taqu/items/110a37df328b6a82c655 + + +- 参考 +https://github.com/tarinaihitori/leetcode/pull/11#pullrequestreview-2405412105 +https://github.com/takumihara/leetcode/pull/1/files +https://github.com/rihib/leetcode/pull/8/files +https://github.com/colorbox/leetcode/pull/3 + + +# step3 + +今度は、時間を測りながら、もう一回、書きましょう。書いてアクセプトされたら文字消してもう一回書く。これを10分以内に一回もエラーを出さずに書ける状態になるまで続ける。3回続けてそれができたらその問題はOK。 + +実施しました。 + + +```c++ +class Solution { +public: + vector twoSum(vector& nums, int target) { + map num_to_indexes = {}; + for (int i = 0; i < size(nums); i++) { + int diffrence = target-nums[i]; + if (num_to_indexes.contains(diffrence)) { + return{i,num_to_indexes[diffrence]}; + } + num_to_indexes[nums[i]] = i; + } + return {}; + } +}; +```