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

【Python】値の差とインデックスの差が一致する部分列の最大合計を求める方法

nums という数値のリストがあるとします。このリストから、「値が狭義に増加しており、かつ任意の2つの値の差が、それぞれのインデックス(位置)の差と一致する」という条件を満たす部分列を選びます。そして、そのような部分列の合計の最大値を求めることが目的です。

たとえば、入力が nums = [6, 7, 9, 9, 8, 5] の場合、出力は 22 になります。これは、部分列 [6, 7, 9](対応するインデックスは [0, 1, 3])を選ぶと、隣接する値同士の差が [1, 2] となり、これがインデックスの差と一致するためです。

解法のアプローチ

この問題を解くために、以下の手順に従います。

  • d を空のマップ(辞書)として初期化します
  • nums の各インデックス i と各値 x について、次の処理を行います
    • d[x − i] に x を加算します(d[x − i] := d[x − i] + x)
  • d のすべての値の中から最大値を返します

ここでのポイントは「x − i」というキーです。ある要素について「値 − インデックス」の結果が同じであれば、それらの要素は「値の差 = インデックスの差」という条件を満たす同一のグループに属することになります。したがって、同じキーを持つ要素の値をすべて合計すれば、条件を満たす部分列の合計が自然に得られます。

理解を深めるために、以下の実装例を見てみましょう。

実装例

class Solution:
    def solve(self, nums):
        from collections import defaultdict
        d = defaultdict(int)
        for i, x in enumerate(nums):
            d[x - i] += x
        return max(d.values())

ob1 = Solution()
nums = [6, 7, 9, 9, 8, 5]
print(ob1.solve(nums))

入力

[6, 7, 9, 9, 8, 5]

出力

22

計算量について

このアルゴリズムの時間計算量は O(n)、空間計算量も O(n) です。リストを一度走査するだけで答えが求まるため、非常に効率的な解法と言えます。defaultdict を使うことで、キーの存在チェックを省略でき、コードも簡潔になります。

  1. Pythonで配列の合計を求める方法を徹底解説

    この記事では、Pythonを使って配列(リスト)の合計を求める方法について詳しく解説します。 問題文 問題: 配列が与えられたとき、その配列に含まれるすべての要素の合計を計算してください。 最も基本的なアプローチは、配列全体を走査し、各インデックスの要素を順番に加算していく方法です。ここでは、まず組み込み関数を活用したシンプルな実装例を見ていきましょう。 方法1:組み込み関数 sum() を使う Pythonには、イテラブルなオブジェクトの合計を一発で計算できる組み込み関数 sum() が用意されています。これを使えば、コードは非常に簡潔になります。 サンプルコード # 合計を求める関数 de

  2. Pythonで配列(リスト)の合計を求める方法をわかりやすく解説

    この記事では、配列(リスト)の合計値を求めるという問題に対して、Pythonでの解決策とアプローチをわかりやすく解説します。 問題の定義 配列が入力として与えられたとき、その配列に含まれるすべての要素の合計を計算することを目標とします。 例えば、[1, 2, 3, 4, 5] という配列が与えられた場合、出力は 15 になります。 アプローチ1:ループを使った素朴な方法(総当たり法) 最も基本的な方法は、リストを先頭から順に走査し、各要素を合計用の変数に加算していくやり方です。手順は以下の通りです。 合計を格納する変数を 0 で初期化します。 for ループでリストの各要素を取り出し、順番に