diff --git a/560. Subarray Sum Equals K.md b/560. Subarray Sum Equals K.md new file mode 100644 index 0000000..8d9b8f2 --- /dev/null +++ b/560. Subarray Sum Equals K.md @@ -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の部分に線を引いて、ぶつかったところと考えれば良さそう。 +- 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 + 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 + 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 +``` + +書きにくい。 \ No newline at end of file