Kadane’s Algorithm - Maximum subarray problem
アルゴリズムの問題をここ1年ほど解いているのですが、Kadane’s Algorithmというのを知ったので、というかまた間違えたので自身の復習も兼ねてアウトプットとして解説記事にします。
Maximum subarray problem
Maximum subarray problemとは次のようなシンプルな問題です:
次の1次元配列が与えられたとき
この
ex.
この解法としては直観的なBrute Forceの他に本記事で取り上げるKadane's Algorithmがあります。
計算量は以下のとおりです:
- Brute Force:
\mathcal{O}(N^2) - Kadane's Algorithm:
\mathcal{O}(N)
直観的なBrute Forceに比較してなんと線形時間でできてしまうのが面白いですね。
Brute Force
まずはBrute Forceを考察してみましょう。
それぞれ部分列の最初と最後を考えて部分和を計算し、その最大値を記録します。
このアルゴリズムは
def brute_force(nums: List[int]):
n = len(nums)
max_sum = -inf
for i in range(n):
cur_sum = 0
for j in range(i, n):
cur_sum += nums[j]
max_sum = max(max_sum, cur_sum)
return max_sum
Intuition & Easy Proof
さてKadane's Algorithmを使えばこの計算が
厳密な証明ではありませんがアイディアの核心を見たいと思います。
まず
今
もう
このとき次に考えるべき区間の最初のindexはどこでしょうか?
この答えが
なぜならば
よって
Implementation
実装に際してもう1点注意しなければならないのは、全要素が負 i.e. 任意の
Pythonによる実装は以下の通りです:
def kadane(nums: List[int]):
cur_sum = max_sum = nums[0]
for n in nums[1:]:
cur_sum = max(cur_sum+n, n)
max_sum = max(max_sum, cur_sum)
return max_sum
Reference
- Maximum subarray problem - Wikipedia
- Official Solution - Maximum Subarray - LeetCode
- Kadane’s Algorithm: An Efficient Way to Find Maximum Subarray
- Kadane's Algorithm | 最大部分配列 問題
Problems
情報求む
LeetCode
- Maximum Subarray - LeetCode : 基礎
- Maximum Absolute Sum of Any Subarray - LeetCode
- Maximum Sum Circular Subarray - LeetCode : 応用
Discussion