Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで昇順部分配列の最大合計を求めるプログラムの書き方

この記事では、正の値のみで構成された配列 nums が与えられたとき、その中に存在する「昇順の部分配列(サブアレイ)」の中で、合計が最大になるものを求める方法を解説します。

問題の定義

部分配列 [nums_l, nums_l+1, ..., nums_r-1, nums_r] が「昇順」であるとは、l <= i < r を満たすすべての i について nums[i] < nums[i+1] が成り立つことを指します。

たとえば、入力が nums = [15, 25, 35, 5, 15, 55] の場合、出力は 75 になります。これは、[5, 15, 55] が合計値最大の昇順部分配列だからです。

アルゴリズムの考え方

この問題は、配列を一度だけ走査する線形時間 O(n) のアルゴリズムで効率的に解けます。手順は以下のとおりです。

  • 変数 totalmax_total を、どちらも nums[0] で初期化します。
  • i を 1 から配列の末尾まで順に処理します。
    • nums[i] > nums[i-1] の場合:現在の昇順が続いているので、total += nums[i] として合計に加算します。
    • それ以外の場合:昇順が途切れたため、total = nums[i] として新しい部分配列の起点とします。
  • 各ステップで total > max_total ならば、max_total = total として最大値を更新します。
  • 最後に max_total を返します。

Pythonでの実装例

def solve(nums):
    total = nums[0]
    max_total = nums[0]
    for i in range(1, len(nums)):
        if nums[i] > nums[i-1]:
            total += nums[i]
        else:
            total = nums[i]
        if total > max_total:
            max_total = total
    return max_total

nums = [15, 25, 35, 5, 15, 55]
print(solve(nums))

入力

[15, 25, 35, 5, 15, 55]

出力

75

処理の流れを追ってみる

上記の例では、まず 15 → 25 → 35 と昇順が続くため total は 75 になります。次に 5 で昇順が崩れるため total は 5 にリセットされ、その後 5 → 15 → 55 で再び 75 となります。結果として最大値 75 が出力されます。

この手法は「カダネのアルゴリズム」の応用であり、計算量は O(n)、追加メモリは O(1) で済むため、大きな配列に対しても高速に動作します。

  1. Pythonで最大の合計を持つ連続サブリスト(部分配列)の合計を求めるプログラム

    配列 A が与えられたとき、「最大の合計を持つ連続した部分リスト(サブアレイ)」を見つけ、その合計値を返すことを考えます。例えば、配列が A = [-2, 1, -3, 4, -1, 2, 1, -5, 4] の場合、答えは合計 6 となり、該当する部分配列は [4, -1, 2, 1] です。解き方:動的計画法(DP)の活用この問題は、動的計画法(Dynamic Programming)を使うことで効率的に解けます。基本的な考え方は、「各位置で終わる部分配列の合計の最大値」を順番に求めていくというものです。配列 A と同じサイズの配列 dp を用意し、すべて 0 で初期化するdp[0] :=

  2. Pythonで解く最大積部分配列問題【動的計画法の実装例】

    問題の概要 整数配列 nums が与えられたとき、配列内の連続する部分配列(少なくとも1つの要素を含む)の中で、積が最大になるものを見つける問題です。 例えば、配列が [2,3,-2,4] の場合、出力は 6 になります。これは連続する部分配列 [2,3] の積 2×3=6 が最大だからです。 解法のアプローチ この問題は動的計画法(DP)を活用して解くのが効果的です。重要なポイントは、配列に負の数が含まれる可能性があることです。負の数同士を掛け合わせると正の数になるため、それまでの「最小の積」が突然「最大の積」に変わることがあります。 そこで、各インデックスにおいて「その位置で終わる部分配