1. 標準例 -> 6
  2. 1 要素 [-1] -> -1
  3. 全部正 [5, 4, -1, 7, 8] -> 23
  4. 全部負 [-3, -1, -2] -> -1
  5. 1 要素 [42] -> 42
  6. [1, 2, 3, -10, 4, 5] -> 9
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
最大部分配列和 (Kadane)

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

最大部分配列和 (Kadane)

全部の区間を試すと間に合わない

[-2, 1, -3, 4, -1, 2, 1, -5, 4] から連続した区間を 1 つ選んで、合計を一番大きくします。答えは 4, -1, 2, 1 の 6 です。今度は飛ばせません。区間なので、始まりと終わりを決めたら、間の要素は全部入ります。

始まりと終わりを総当たりすると、こんな形になります。

Python

for i in range(len(nums)): for j in range(i, len(nums)): ... # nums[i] から nums[j] までの合計を見る

正しい答えは出ますが、要素が 10 万個になると 50 億回の足し算になります。配列を 1 度通り抜けるだけで答えを出したいところです。

足を引っ張るなら、そこで捨てる

左から 1 個ずつ見ていき、「今の要素で終わる区間の合計」だけを持ち歩きます。次の要素が来たときの判断は 1 つだけです。

これまでの合計がマイナスなら、そこまでを捨てて、新しい要素から始め直す。

理由は単純です。これまでの合計がマイナスなら、それを引き継いだ時点で、次の要素の単独より必ず小さくなります。プラスなら、引き継いだほうが必ず大きくなります。次の要素が何であるかは関係ありません。だから、その場で決めてしまってよいのです。

先ほどの配列で追ってみます。

  • -2 から始めて合計は -2。マイナスなので捨てる
  • 1 から始め直して合計 1
  • 次は -3。1 はプラスなので引き継いで合計 -2。マイナスになった
  • 次は 4。捨てて 4 から始め直す
  • -1 を足して 3、2 を足して 5、1 を足して 6
  • 次は -5。6 はプラスなので引き継いで 1
  • 最後の 4 を足して 5

途中で出てきた一番大きい値は 6 です。捨てるか引き継ぐかを、その場の合計だけで決められるのがこの解き方の肝です。先の要素を見に行く必要がないので、配列を左から 1 度なぞるだけで答えが出ます。

ですから持ち歩くのは「今の合計」と「今までで一番大きかった値」の 2 つだけで足ります。今の合計が下がったときに一番大きかった値まで下げてしまわないよう、2 つは別々に持ちます。

全部マイナスのときに 0 を返さない

よくある書き間違いは、合計がマイナスになったときに 0 に戻してしまうことです。それだと [-3, -1, -2] でも 0 を返しますが、この課題は 1 要素以上を必ず選ぶ ので、答えは -1 です。

0 に戻すのではなく、その要素の値から始め直す。こう書いておけば、全部マイナスでも自然に一番大きい単独の要素が残ります。一番大きかった値を入れる変数も、0 ではなく先頭の要素で始めます。

やってみよう

  • [5, 4, -1, 7, 8] は全部足すのが最大で 23。途中の -1 を捨てないほうが得
  • [-1] の答えは -1。要素が 1 つならそれを選ぶしかない
  • [42] のように 1 要素だけの配列で、ループが 1 度も回らなくても答えが出るか確かめる
  • どこからどこまでを選んだかも返したい場合を考える。捨てて始め直した位置が、区間の始まりになる

要件

  1. 戻り値は連続部分配列の最大和 (整数)
  2. 1 要素以上を必ず選ぶ (空区間は不可、全要素負のときは最大の単独要素を返す)
  3. Kadane のアルゴリズム O(n) で解くこと

入出力例

maxSubArray([-2,1,-3,4,-1,2,1,-5,4]) → 6 maxSubArray([-1]) → -1 maxSubArray([5,4,-1,7,8]) → 23 maxSubArray([-3,-1,-2]) → -1 maxSubArray([42]) → 42 maxSubArray([1,2,3,-10,4,5]) → 9

ヒント

current を「i 番目で終わる部分配列の最大和」、best を「全体の最大」として 2 変数で進める

更新式は current = max(nums[i], current + nums[i])。これが「伸ばすか / 始め直すか」の判断

current = max(0, ...) と書かないこと。空区間 0 を許してしまい、全部負のケースで誤答する

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 隣り合わない最大値 (House Robber)

    隣り合う要素を同時に選べないという制約の下、配列から取り出せる最大合計を DP で求めます。

  • グリッド経路数 (Unique Paths)

    右と下にのみ進めるグリッドの上で、左上から右下に至る経路の総数を二次元 DP で数えます。

  • 単語分割可能か (Word Break)

    辞書にある単語の連結で対象文字列を構成できるかを判定する Word Break 問題を、DP で線形時間に近い計算量で解きます。

  • 第6章まとめクイズ — 動的計画法 (上級)

    編集距離、LIS、Kadane、House Robber、グリッド経路数、Word Break の理解度を確認する 4 択クイズです。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 配列サイズ固定の同型データの集まり
  • 判断YES/NO 分岐を表す菱形
  • 変数データに名前をつけて参照する仕組み
  • ループ繰り返し処理。矢印で戻すか専用記号で示す
  • 戻り値呼び出し元への返答を表す点線矢印
  • アルゴリズム問題を効率よく解く手順
main.py
学習モード
エディタを読み込んでいます

メモ

最大部分配列和 (Kadane)

⌘S で保存