ゆめさくエンジニア研究所

続いた​区間の​合計の最大

整数の​並びから、​続いた​区間の​合計の​うち最大の​値を​求める。​「ここで​終わる​区間の​最大」を​ 1 つ​持ち​歩き、​並びを​ 1 回なめるだけで​解く​考え方の​練習です。

問題

整数の並び nums を受け取ります。nums の中で、続いて並んだ 1 つ以上の要素を選んだとき、その合計のうち最大の値を返す関数を書いてください。

  • 選ぶ区間は 1 つ以上の要素を含みます。何も選ばない (合計 0) は数えません
  • 全部が負の数なら、いちばん大きい 1 つだけを選んだ値が答えになります
  • nums の長さは 1 以上 100000 以下、値はどれも -10000 以上 10000 以下です

入力と出力の例

例 1

4、-1、3 と続く区間の合計 6 が最大です。

入力

nums = [2, -5, 4, -1, 3, -6, 1]

出力

6

例 2

全部が負の数なので、いちばん大きい -2 だけを選びます。

入力

nums = [-7, -2, -9]

出力

-2

例 3

真ん中の -1 をまたいでも、両端の 5 を合わせたほうが大きくなります。

入力

nums = [5, -1, 5]

出力

9

面接での聞かれ方

面接では、次のように短く渡されることが多いです。

  • 「整数の配列で、続いた部分の合計の最大を求めてください」
  • 書き終えたあとに「その区間の始まりと終わりの位置も返せますか?」と広げて聞かれます
  • 「全部負の数だったら、答えはどうなりますか?」と端の場合を聞かれることもあります

何も選ばない場合を 0 として数えるかどうかで答えが変わるので、最初に確かめておきます。

まず考える手順

段 1

まずは素直に、区間を全部試します。始まりの位置と終わりの位置を 2 重の繰り返しで回し、始まりを決めたら終わりを 1 つずつ延ばしながら合計を足していきます。これで O(n²) で解けますが、長さが 100000 だと約 50 億回の足し算になります。

段 2

見方を変えて、「位置 i で終わる区間の中で、合計が最大の物」を考えます。その区間は、i の値だけか、「i - 1 で終わる最大の区間」に i の値を付け足した物か、のどちらかです。前の区間の合計が負なら、付け足すと損なので、i から新しく始めたほうが大きくなります。

段 3

この「ここで終わる区間の最大」は、すぐ前の値だけから決まります。なので並びを前から 1 回なめながら、その値を 1 つだけ持ち歩きます。あわせて、これまでに出てきた中で一番大きい値を別に覚えておけば、それが答えです。

ここから​解答です。​先に​自分で​書いてから​読むと、​考え方が​残ります。

解答

Python

Python

def max_run_sum(nums):
    best = cur = nums[0]
    for x in nums[1:]:
        cur = max(x, cur + x)
        best = max(best, cur)
    return best

JavaScript

JavaScript

function maxRunSum(nums) {
  let cur = nums[0];
  let best = nums[0];
  const n = nums.length;
  for (let i = 1; i < n; i++) {
    const x = nums[i];
    cur = Math.max(x, cur + x);
    best = Math.max(best, cur);
  }
  return best;
}

cur が「いまの位置で終わる区間の最大」、best が「これまでで一番大きい合計」です。どちらも最初の要素から始めるので、全部が負の数でも正しく答えられます。

計算量

  • 時間は O(n) です。並びを前から 1 回なめるだけです
  • 使う記憶は O(1) です。持ち歩くのは 2 つの数だけです。Python で 2 つ目以降を切り出すと写しを作るので、気になる場合は位置で回します
  • 段 1 の全部を試す書き方は、かかる時間が O(n²) になります

よくある間違い

  • 一番大きい値を 0 から始める。 best = 0 で始めると、全部が負の数のときに 0 を返してしまいます。例 2 の答えは -2 です。最初の要素で始めます
  • 最後の cur を返す。 cur は「最後の位置で終わる区間」の最大でしかありません。例 1 では最後の 1 で終わる区間の最大は 1 で、答えの 6 とは違います
  • 負の数が来たら区切る。負の要素をまたいだほうが大きくなることがあります。例 3 では -1 を含めた 9 が答えです。区切るかどうかは、要素 1 つの符号ではなく、それまでの合計が負かどうかで決めます

面接での話し方の例

書き始める前に、方針を短く口に出します。

「区間を全部試すと O(n²) です。代わりに、各位置で終わる区間の最大を前から順に求めます。前までの合計が負なら捨ててここから始め、そうでなければ付け足します。これまでの最大を別に覚えておけば、1 回なめるだけで O(n) で解けます。」

書き終えたら、例を 1 つ手でたどって見せます。

「例 1 でたどります。2 から始め、-5 では付け足すと -3、-5 だけなら -5 なので -3 です。次の 4 では、前が -3 で負なので捨てて 4 から始めます。-1 で 3、3 で 6 となり、ここで最大の 6 を覚えます。そのあとの -6 と 1 では 6 を超えないので、答えは 6 です。」

解答を動かした版 Python 3.12.14Node.js 22.23.4確認日 2026年10月24日

コーディング面接問題の一覧へ戻る