-
Notifications
You must be signed in to change notification settings - Fork 0
Add 560. Subarray Sum Equals K.md #17
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?
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,126 @@ | ||
# step 1 | ||
まず、以下でTLE | ||
```python | ||
class Solution: | ||
def subarraySum(self, nums: List[int], k: int) -> int: | ||
result = 0 | ||
for left in range(len(nums)): | ||
for right in range(left + 1, len(nums) + 1): | ||
if sum(nums[left:right]) == k: | ||
result += 1 | ||
return result | ||
``` | ||
|
||
多少改善させた次のもTLE | ||
```python | ||
class Solution: | ||
def subarraySum(self, nums: List[int], k: int) -> int: | ||
result = 0 | ||
for left in range(len(nums)): | ||
sub_sum = nums[left] | ||
for right in range(left, len(nums)): | ||
if right != left: | ||
sub_sum += nums[right] | ||
if sub_sum == k: | ||
result += 1 | ||
return result | ||
``` | ||
|
||
単調性があるわけでないので、部分和を取る尺取法でもなさそうでよくわからず、解答を見る。 | ||
先頭から集めた部分和から、その部分和となるprefixの数を記録していけば良いみたい。 | ||
|
||
```python | ||
class Solution: | ||
def subarraySum(self, nums: List[int], k: int) -> int: | ||
prefix_subsum = 0 | ||
subsum_to_count = {0: 1} | ||
result = 0 | ||
|
||
for num in nums: | ||
prefix_subsum += num | ||
result += subsum_to_count.get(prefix_subsum - k, 0) | ||
|
||
if prefix_subsum not in subsum_to_count: | ||
subsum_to_count[prefix_subsum] = 0 | ||
subsum_to_count[prefix_subsum] += 1 | ||
return result | ||
``` | ||
|
||
# step 2 | ||
- https://discord.com/channels/1084280443945353267/1233603535862628432/1252232545056063548 | ||
- 駅と標高を使って、累積和を高低差みたいに捉えている。 | ||
- わかりやすい。今いる地点から標高差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. はじめから [0] = 1 であることがしっくり来ていたらこの話は問題ないと思います。 https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0 |
||
- https://github.com/olsen-blue/Arai60/pull/16/files | ||
- cumulative_sumを使っていた。 | ||
- 自分はprefix_sumとしていたけど、こっちの方がわかりやすい気がする。 | ||
- https://github.com/katataku/leetcode/pull/15/files/7728d62d9ce2b77372315886a9bbcd25dfb0cd32#r1898174496 | ||
- num_subarraysの方がわかりやすく感じた。 | ||
- subarraySum(nums, k)と与えられた時に、resultだけだと部分和か何かが返ってきそうに感じる | ||
|
||
```python | ||
from collections import defaultdict | ||
|
||
|
||
class Solution: | ||
def subarraySum(self, nums: List[int], k: int) -> int: | ||
cumulative_sum = 0 | ||
cumulative_sum_to_count = defaultdict(int) | ||
cumulative_sum_to_count[0] = 1 | ||
subarrays_count = 0 | ||
for num in nums: | ||
cumulative_sum += num | ||
subarrays_count += cumulative_sum_to_count.get( | ||
cumulative_sum - k, | ||
0 | ||
) | ||
cumulative_sum_to_count[cumulative_sum] += 1 | ||
Comment on lines
+72
to
+76
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. cumulative_sum_to_countにdefaultdictを使う場合、シンプルに 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. それをすると、cumulative_sum_to_count[cumulative_sum - k] = 0が追加されて不要なメモリ使用が増えそうだから避けようくらいの考えでした。 |
||
return subarrays_count | ||
``` | ||
|
||
# step 3 | ||
|
||
```python | ||
from collections import defaultdict | ||
|
||
|
||
class Solution: | ||
def subarraySum(self, nums: List[int], k: int) -> int: | ||
cumulative_sum = 0 | ||
cumulative_sum_to_count = defaultdict(int) | ||
cumulative_sum_to_count[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. この行にコメントを付けたいと思いました。 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. 個人的には、L88-L91までは初期化の塊と認識していて、コメントの必要は感じていませんでした。 ただ、そのイメージを伝え切れるコードではなかったかもしれません。 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. つけるコメントを考えてみたのですが、なかなかいいものが思いつかなかったので、やっぱりなくてもいいかもしれません。 |
||
subarrays_count = 0 | ||
for num in nums: | ||
cumulative_sum += num | ||
subarrays_count += cumulative_sum_to_count.get( | ||
cumulative_sum - k, | ||
0 | ||
) | ||
cumulative_sum_to_count[cumulative_sum] += 1 | ||
return subarrays_count | ||
``` | ||
|
||
# step 4 | ||
コメントの有無、条件分岐を少し簡潔に書くためのコメントをいただいた。 | ||
|
||
[setdefault](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) | ||
を使ってみる。 | ||
|
||
```python | ||
class Solution: | ||
def subarraySum(self, nums: List[int], k: int) -> int: | ||
cumulative_sum = 0 | ||
cumulative_sum_to_count = {} | ||
cumulative_sum_to_count[0] = 1 | ||
num_subarrays_with_sum_k = 0 | ||
for num in nums: | ||
cumulative_sum += num | ||
num_subarrays_with_sum_k += cumulative_sum_to_count.get( | ||
cumulative_sum - k, 0 | ||
) | ||
cumulative_sum_to_count[cumulative_sum] = ( | ||
cumulative_sum_to_count.setdefault(cumulative_sum, 0) + 1 | ||
) | ||
return num_subarrays_with_sum_k | ||
``` | ||
|
||
書きにくい。 |
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.
sub_sum = 0
から始めれば、if right != left:
のチェックなしでsub_sum
に追加していけます。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.
確かにそうですね。ありがとうございます!