560. Subarray Sum Equals K#16
Conversation
| - `k`未満ならば、`right`を進める | ||
|
|
||
| という解法をまず思いついた。 | ||
| しかし、これは`nums[i] > 0`が前提のため、今回は不適切。 |
There was a problem hiding this comment.
なんとなくですが、この解法ができそうなのは、nums1がソートされているという前提も必要そうです。
いかがでしょうか。
ちょっと考えていたのですが、必要のは非負だけでした。すみません。。。
非負ではなく自然数でした。すみません...
There was a problem hiding this comment.
この文面では分かりづらいですが、numsがソートされてなくても大丈夫なつもりで考えていました。
以下のコードが意図していたものです。
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
left = 0
partial_sum = 0
count = 0
for right in range(len(nums)):
partial_sum += nums[right]
while partial_sum >= k and left <= right:
if partial_sum == k:
count += 1
partial_sum -= nums[left]
left += 1
return countnums[i]>0だとすると、
sum(nums[i:j]) > sum(nums[i:j]) - nums[i] == sum(nums[i+1:j])sum(nums[i:j]) < sum(nums[i:j]) + nums[j+1] == sum(nums[i:j+1])
という関係が成り立ちます。
これを用いて、
sum(nums[left: right])) >= kならばleftを増やすsum(nums[left: right])) < kならばrightを増やす
という方針で考えました。(時間O(n), 空間O(1))
ただ0以下の数が混じると上述の関係が崩れるので、今回は使えませんでした。
There was a problem hiding this comment.
おっしゃる通りですね。丁寧に説明していただきありがとうございます。
・leftとrightの区間が k以上になるまでrightを進める。
・leftとrightの区間が k未満になるかleftがrightに追いつくまでleftを進める。
をやりながら、部分和がkになる回数を数えるのですね。
よくわかりました。ありがとうございます!
There was a problem hiding this comment.
入力条件を変えながら、それに応じた解法をすぐに思い浮かべられるのは、とても良いですね。
There was a problem hiding this comment.
頭では考えていたのですが、実際には書いていなかったので良い機会になりました。
いつも丁寧なレビューありがとうございます。
今後もよろしくお願いします!
| prefix_sum_count[current_sum] += 1 | ||
|
|
||
| return count | ||
|
|
There was a problem hiding this comment.
ふわっとした感想ですが、
step1の段階でこういったコードが書けるのは、とてもいいなと感じました。
解きかたとコードの対応がとりやすいです。
| prefix_sum_count[0] = 1 | ||
|
|
||
| count = 0 | ||
| current_sum = 0 |
今回の問題
https://leetcode.com/problems/subarray-sum-equals-k/
次回の問題
https://leetcode.com/problems/number-of-islands/