Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions 53/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 53. Maximum Subarray

- 愚直にsol1.pyを書いた
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nums[i] までの累積和を c[i] としたとき、i = 0 ... len(nums)-1 を舐めながら最大となる c[i] - c[j] (j < i) を探す。つまり min(c[j]) を探しながら、maxを c[i] - c[j] で更新していく、というのが考え方だと思います。累積和の算出とこの更新が一度の走査でできる形で書けるのは「愚直」ではなく、それなりに工夫されていると感じました。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(他の方からも指摘を受けたのですが)「愚直」は「見て思いついたまま」という意味で使っていました。
言い方を改めるようにします

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「愚直」は「見て思いついたまま」という意味

この意味はまあ正しくて、「見て思いついたまま」累積和の算出とこの更新を一度の走査でやるように書けた、というのがすごいなあと思った、という感想でした。言い方を改める必要は特に感じませんでした。

- 計算量 O(n)
- Kadaneのアルゴリズム
- https://en.wikipedia.org/wiki/Maximum_subarray_problem
- https://qiita.com/awesam/items/37a0ceb1468feef3a403
- https://ark4rk.hatenablog.com/entry/2018/01/08/002508
- 自然言語で説明すれば、「arrayを一巡し、各要素(a_iとする)で終わるものが最大値になりうるかを検証する。一つ前の要素で終わったsubarrayの最大値を記録しておけば、それにa_iを加えたものかa_iだけのsubarrayがa_iで終わったarrayの最大値である」
- sol2.py
- 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って配列の最初からではなくてもそう呼ぶのかな
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

配列の最初から、とするのが一般的みたいですね。
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_sumcumulative_sum じゃないよね、ということでしょうか?

Copy link
Copy Markdown
Owner Author

@tom4649 tom4649 Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

max_cumulative_sum は cumulative_sum じゃないよね、ということでしょうか

この意図で書きましたがなるほど、prefix sumとcumulative sumの区別があるのですね。
自分で調べればよかったです、ありがとうございます。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ご指摘の通り、リンク先のコードの max_cumulative_summax_sum くらいにしておくのが適切そうです。

prefix sumとcumulative sumの区別があるのですね。

cumulative sum と書いたとき、文字通り(配列の先頭ではないどこかから)累積した和、とも、いわゆる累積和 (=prefix sum) とも取れるので、区別したからといって受け手にもその意図で伝わるとは限らないように思いました。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

誤解を極力避けるという姿勢、勉強になります。
(僕は prefix sumもcumulative sumも「累積和」として区別なく覚えていました。)

- https://github.com/mamo3gr/arai60/blob/53_maximum-subarray/53_maximum-subarray/step3.py
- > マイナスなら相続をやめる
- https://github.com/mamo3gr/arai60/blob/53_maximum-subarray/53_maximum-subarray/step2.py
- 分割統治法, O(Nlog N)


11 changes: 11 additions & 0 deletions 53/sol1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
max_sum = -float("inf")
cumulative_sum = 0
min_cumulative_sum = 0
for n in nums:
cumulative_sum += n
max_sum = max(max_sum, cumulative_sum - min_cumulative_sum)
min_cumulative_sum = min(min_cumulative_sum, cumulative_sum)

return max_sum
9 changes: 9 additions & 0 deletions 53/sol2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
max_so_far = -float("inf")
max_ending_with_n = -float("inf")
for n in nums:
max_ending_with_n = max(n, max_ending_with_n + n)
max_so_far = max(max_so_far, max_ending_with_n)

return max_so_far