-
Notifications
You must be signed in to change notification settings - Fork 0
1.Two Sum #2
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
base: master
Are you sure you want to change the base?
1.Two Sum #2
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,124 @@ | ||
| <問題> | ||
| https://leetcode.com/problems/two-sum/ | ||
|
|
||
| # step1 | ||
|
|
||
| 5分程度答えを見ずに考えて、手が止まるまでやってみる。 | ||
| 何も思いつかなければ、答えを見て解く。 | ||
| ただし、コードを書くときは答えを見ないこと。 | ||
| 正解したら一旦OK。 | ||
| 思考過程もメモしてみる。 | ||
|
|
||
| ```c++ | ||
| class Solution { | ||
| public: | ||
| vector<int> twoSum(vector<int>& 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分探索が必要となる。一度自分で書いてみる。 | ||
|
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. 配列をソートしてあれば、先頭から後方に進めていくポインターと、末尾から前方に進めていくポインターを用意しておき、値の和が小さければ先頭のポインターを進める、値の和が大きければ後方のポインターを進める、を繰り返していく方針も取れると思います。
Owner
Author
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. ありがとうございます! |
||
|
|
||
| # step2 | ||
| 他の方が描いたコードを見て、参考にしてコードを書き直してみる。 | ||
| 参考にしたコードのリンクは貼っておく。 | ||
| 読みやすいことを意識する。 | ||
| 他の解法も考えみる。 | ||
|
|
||
| 計算量:O(N) | ||
|
|
||
|
|
||
| ```c++ | ||
| class Solution { | ||
| public: | ||
| vector<int> twoSum(vector<int>& nums, int target) { | ||
| map<int, int> num_to_indexes = {}; | ||
| for (int i = 0; i < size(nums); i++) { | ||
| int diffrence = target-nums[i]; | ||
|
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.
https://google.github.io/styleguide/cppguide.html#Horizontal_Whitespace
|
||
| if (num_to_indexes.contains(diffrence)) { | ||
| return{i,num_to_indexes[diffrence]}; | ||
|
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.
https://google.github.io/styleguide/cppguide.html#Horizontal_Whitespace
Owner
Author
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. 丁寧にコードを見ていただきありがとうございます! |
||
| } | ||
| 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分木、問題の分類として | ||
|
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. 実際にはRed-Black Treeで実装されることが一般的だそうです。self-balanced binary search treeとしては、他にAVL木などもありますね。self-balancedということで、binary search treeの偏りの問題に対して、回転という操作を加えることでworst caseの深さがO(n)にならないようにするデータ構造です。 https://stackoverflow.com/questions/2558153/what-is-the-underlying-data-structure-of-a-stl-set-in-c
Owner
Author
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. 平衡二分木は一つでいいので聞かれたときに、こういう感じのやつと答えられるようにしておくといいと思います。 |
||
| Hashになっているので、Hashを使った方法もあるはず。 | ||
| unordered_mapはハッシュデーブルで実装されているらしい。 | ||
| こちらも使ってよさそう。→ | ||
| https://cpprefjp.github.io/reference/unordered_map/unordered_map.html | ||
|
|
||
| ちなみにsetは二分木 | ||
|
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. setはmapの特殊形として実装されるのが一般的だと思うので、setもRed-Black Treeで実装されることが多いと思います。
Owner
Author
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. すみません、setがmapの特殊形というもは、mapでいうkeyが、 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. そうですね。木の各ノードに持たせる情報が、mapだとkey,valueのペアをもたせますが、setだとvalue(あるいはkey)のみをもたせるだけの違いですね。 |
||
| 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<int> twoSum(vector<int>& nums, int target) { | ||
| map<int, int> 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 {}; | ||
| } | ||
| }; | ||
| ``` | ||
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.
私は - 1 しないかもしれないですね。(どうせ空のループが回るだけなので。)
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.
ありがとうございます。
範囲の端はシンプルなほうが読みやすいコードになるので、
今後はそういう観点でもコードを書けるようにしていきます。