From e12998c0cb4a3ce0051d7be9cb9a971eeef550bd Mon Sep 17 00:00:00 2001 From: busker <165013324+hiroki-horiguchi-dev@users.noreply.github.com> Date: Sun, 17 May 2026 19:55:40 +0900 Subject: [PATCH 1/2] Create 560.md --- hashmap/560.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 hashmap/560.md diff --git a/hashmap/560.md b/hashmap/560.md new file mode 100644 index 0000000..a2b0bb0 --- /dev/null +++ b/hashmap/560.md @@ -0,0 +1,62 @@ +- 問題: [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であるに言い換えられており、これをプログラム上表現しなければいけないと思うこと +- 条件 + - 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) { + + Map prefixCount = new HashMap<>(); + prefixCount.put(0, 1); + int prefixNum = 0; + int result = 0; + + for(int num : nums) { + prefixNum += num; + int target = prefixNum - k; + if (prefixCount.containsKey(target)) { + result += prefixCount.get(target); + } + prefixCount.put(prefixNum, prefixCount.getOrDefault(prefixNum, 0) + 1); + } + + return result; + } +} +``` + +# Cluadeレビュー +- O(N)の方針は全く思いつかなかったので、壁打ちしつつやったため最後に受けるレビューは特になし \ No newline at end of file From 32fae4e60c0a3ab7ea1df6ce5949b618a8e805f5 Mon Sep 17 00:00:00 2001 From: busker <165013324+hiroki-horiguchi-dev@users.noreply.github.com> Date: Sun, 17 May 2026 19:58:58 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E6=AE=8B=E3=82=8A=E3=81=AE=E3=82=B3?= =?UTF-8?q?=E3=83=A1=E3=83=B3=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hashmap/560.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hashmap/560.md b/hashmap/560.md index a2b0bb0..e8c454b 100644 --- a/hashmap/560.md +++ b/hashmap/560.md @@ -12,6 +12,10 @@ 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