Conversation
| - https://discord.com/channels/1084280443945353267/1206101582861697046/1207518775851876362 | ||
| - sol1.pyと同じ考え | ||
| - https://github.com/mamo3gr/arai60/blob/53_maximum-subarray/53_maximum-subarray/step1.py | ||
| - cumulative sumって配列の最初からではなくてもそう呼ぶのかな |
There was a problem hiding this comment.
配列の最初から、とするのが一般的みたいですね。
https://www.geeksforgeeks.org/dsa/understanding-prefix-sums/
Prefix Sum: A prefix sum is the cumulative sum of elements of an array from the beginning up to a given index.
max_cumulative_sum は cumulative_sum じゃないよね、ということでしょうか?
There was a problem hiding this comment.
max_cumulative_sum は cumulative_sum じゃないよね、ということでしょうか
この意図で書きましたがなるほど、prefix sumとcumulative sumの区別があるのですね。
自分で調べればよかったです、ありがとうございます。
There was a problem hiding this comment.
ご指摘の通り、リンク先のコードの max_cumulative_sum は max_sum くらいにしておくのが適切そうです。
prefix sumとcumulative sumの区別があるのですね。
cumulative sum と書いたとき、文字通り(配列の先頭ではないどこかから)累積した和、とも、いわゆる累積和 (=prefix sum) とも取れるので、区別したからといって受け手にもその意図で伝わるとは限らないように思いました。
There was a problem hiding this comment.
誤解を極力避けるという姿勢、勉強になります。
(僕は prefix sumもcumulative sumも「累積和」として区別なく覚えていました。)
53/sol1.py
Outdated
| class Solution: | ||
| def maxSubArray(self, nums: List[int]) -> int: | ||
| max_sum = -float("inf") | ||
| cummulative_sum = 0 |
There was a problem hiding this comment.
cumulative が正しそうです。
| cummulative_sum = 0 | |
| cumulative_sum = 0 |
53/sol2.py
Outdated
| max_sum_end_with_current_n = -float("inf") | ||
| for n in nums: | ||
| max_sum_end_with_current_n = max(max_sum_end_with_current_n + n, n) | ||
| max_sum = max(max_sum, max_sum_end_with_current_n) |
There was a problem hiding this comment.
end_with_current_n の意味が取りづらかったです。多くの場合、current は書き手と読み手との間で「現在」の意味が共有しにくいと感じます。
こんなのはどうでしょうか。
| max_sum_end_with_current_n = -float("inf") | |
| for n in nums: | |
| max_sum_end_with_current_n = max(max_sum_end_with_current_n + n, n) | |
| max_sum = max(max_sum, max_sum_end_with_current_n) | |
| max_sum_ending_at_i = -float("inf") | |
| for i in range(len(nums)): | |
| max_sum_ending_at_i = max(max_sum_ending_at_i + nums[i], nums[i]) | |
| max_sum = max(max_sum, max_sum_ending_at_i) |
さらに丁寧に書くならこういうのもあります。
| max_sum_end_with_current_n = -float("inf") | |
| for n in nums: | |
| max_sum_end_with_current_n = max(max_sum_end_with_current_n + n, n) | |
| max_sum = max(max_sum, max_sum_end_with_current_n) | |
| max_sum_ending_at_i = -float("inf") | |
| for i in range(len(nums)): | |
| extend = max_sum_ending_at_i + nums[i] | |
| start_new = nums[i] | |
| max_sum_ending_at_i = max(extend, start_new) | |
| max_sum = max(max_sum, max_sum_ending_at_i) |
There was a problem hiding this comment.
currentがわかりにくいというのは色々な場所で指摘がありますね。
個人的に添字 i を可読性のためだけに使うことに違和感があったので、以下のように変更しました。
max_so_far = -float("inf")
max_ending_here = -float("inf")
for n in nums:
max_ending_here = max(n, max_ending_here + n)
max_so_far = max(max_so_far, max_ending_here)| @@ -0,0 +1,20 @@ | |||
| # 53. Maximum Subarray | |||
|
|
|||
| - 愚直にsol1.pyを書いた | |||
There was a problem hiding this comment.
nums[i] までの累積和を c[i] としたとき、i = 0 ... len(nums)-1 を舐めながら最大となる c[i] - c[j] (j < i) を探す。つまり min(c[j]) を探しながら、maxを c[i] - c[j] で更新していく、というのが考え方だと思います。累積和の算出とこの更新が一度の走査でできる形で書けるのは「愚直」ではなく、それなりに工夫されていると感じました。
There was a problem hiding this comment.
(他の方からも指摘を受けたのですが)「愚直」は「見て思いついたまま」という意味で使っていました。
言い方を改めるようにします
There was a problem hiding this comment.
「愚直」は「見て思いついたまま」という意味
この意味はまあ正しくて、「見て思いついたまま」累積和の算出とこの更新を一度の走査でやるように書けた、というのがすごいなあと思った、という感想でした。言い方を改める必要は特に感じませんでした。
eef334d to
05b5f77
Compare
53/sol2.py
Outdated
| class Solution: | ||
| def maxSubArray(self, nums: List[int]) -> int: | ||
| max_sum = -float("inf") | ||
| max_ending_here = -float("inf") |
53/sol2.py
Outdated
| @@ -0,0 +1,9 @@ | |||
| class Solution: | |||
| def maxSubArray(self, nums: List[int]) -> int: | |||
| max_sum = -float("inf") | |||
https://leetcode.com/problems/maximum-subarray/submissions/1960731201/