-
Notifications
You must be signed in to change notification settings - Fork 0
Hashmap 560 #16
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: main
Are you sure you want to change the base?
Hashmap 560 #16
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,66 @@ | ||
| - 問題: [560. Subarray Sum Equals K](https://leetcode.com/problems/subarray-sum-equals-k/description/) | ||
| - コメント集: [](https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/mobilebasic#h.e5dwa7yj3tv0) | ||
| - [しっくりこない](https://discord.com/channels/1084280443945353267/1233603535862628432/1252232545056063548) | ||
| - 私もしっくりこなかったのでちょっと寝かせてしまった。 | ||
| - 問題のキモは3つあると思う | ||
| 1. 累積和を使って `prefix[j] - prefix[i] = k` となる2点間を探せばいいと気がつくこと | ||
| - これを式変形して、`prefix[j] - k = prefix[i]` とすること | ||
| - つまり、今(j)までの累積和からkを引いた値が、過去 nums[i] までの累積和と一致していれば、i,j の2点間の差がkだと言えること | ||
| 2. i,j とあたかも二重ループのような話を i は j の過去であると捉え、HashMap の key に nums[i] までの累積和を記録し、value に出現回数を記録すればいいのだ、と気がつくこと | ||
| 3. nums について、「あ、こういうケースがあるな」で思いついたら上記の理屈に当てはめて考えるので、直感とは違う処理をしているように感じる | ||
| 1. 特に番兵(key:0, value:1)のところ | ||
| 2. 例えば、`nums = [1,6,3], k=3, prefix[0,1,7,10]` の時 | ||
| 3. `nums[2] = k` がある、これは即カウントせねば、と直感的に思うんだけれど、、、 | ||
| 4. 上記の考え方をすると、prefix[2] - 3 = 7、つまり prefix[2], prefix[1] 間の差が3であるに言い換えられており、これをプログラム上表現しなければいけないと思うこと | ||
| - [パフォーマンス不足...](https://github.com/Hurukawa2121/leetcode/pull/16#discussion_r1898332261) | ||
| - 私の所属がSIerとかいうところで、バッチがこうなりがちだと思った(早く抜けたい。。) | ||
| - [自然言語で説明できる?](https://discord.com/channels/1084280443945353267/1300342682769686600/1357378682163036160) | ||
| - 意識して書くようにしている | ||
| - 条件 | ||
| - 1 <= nums.length <= 2 * 104 | ||
| - -1000 <= nums[i] <= 1000 | ||
| - -107 <= k <= 107 | ||
| - 方針 | ||
| - ブルートフォース: O(N^2) | ||
| - i,j で全通り走査する | ||
| - j = i + 1 かつ j < nums.size() を満たすように回すところが注意点くらいか | ||
| - 累積和を使う: O(N) | ||
| - 駅の標高と考えてみると、標高差がkとなる2点間を見つければいいとわかる | ||
| - つまり、prefix[j] - prefix[i] = k となる2点を見つける | ||
| - これは prefix[j] - k = prefix[i] と変形できる | ||
| - prefix[i] を記録し続けながら、prefix[j] - k が登場する回数をカウントする | ||
| - prefix[j] = k となる場合、つまり出発点からjまでの累積和がちょうどkになる場合をカウントするため、辞書に key:0, value:1を記録しておく | ||
| - この問題の肝はコメント集のところで触れている | ||
| - 時間計算量 | ||
| - 方針1 O(N^2) | ||
| - 方針2 O(N) | ||
| - 空間計算量 | ||
| - 方針1 O(1) | ||
| - 方針2 O(N): numsのサイズ分 | ||
|
|
||
| # 1st | ||
| ```java | ||
| class Solution { | ||
| public int subarraySum(int[] nums, int k) { | ||
|
|
||
|
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. ありがとうございます。 |
||
| Map<Integer, Integer> prefixCount = new HashMap<>(); | ||
| prefixCount.put(0, 1); | ||
| int prefixNum = 0; | ||
|
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. ありがとうございます。おっしゃる通りだと思います。 |
||
| int result = 0; | ||
|
|
||
| for(int num : 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. if for のあとにスペースが空いているものと空いていないものとで混在しているのが気になりました。 参考までにスタイルガイドへのリンクを共有いたします。 https://google.github.io/styleguide/javaguide.html#s4.6.2-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. ありがとうございます。 |
||
| prefixNum += num; | ||
| int target = prefixNum - k; | ||
|
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. ありがとうございます。 |
||
| if (prefixCount.containsKey(target)) { | ||
| result += prefixCount.get(target); | ||
|
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. なるほど、確かにそうですね。getOrDefault() で1行なら if で明示的に書くより、私もいいと思います。 |
||
| } | ||
| prefixCount.put(prefixNum, prefixCount.getOrDefault(prefixNum, 0) + 1); | ||
|
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. prefixCount.merge(prefixNum, 1, Integer::sum);とも書けるみたいです
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. ありがとうございます、claudeがレビューで出してきました。 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. Goは map[key]++ と書けるのですが、Javaはマップ要素のインクリメントを簡潔に実行する方法なさそうですね
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. Go 便利ですね。 |
||
| } | ||
|
|
||
| return result; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| # Cluadeレビュー | ||
| - O(N)の方針は全く思いつかなかったので、壁打ちしつつやったため最後に受けるレビューは特になし | ||
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.
わたしもはじめよくわからなかったので、図にしてみました。
https://github.com/h-masder/Arai60/pull/17/changes の560_Subarray_Sum_Equals_K/subarraySum_logic.pngです
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.
ありがとうございます。
金銭で例えるのはより身近でわかりやすいと思いました。
自分が納得できる例に問題を言い換えるのも、問題を解く上で重要ですね。