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

Pythonで指定した差を持つ最長等差部分列の長さを求めるプログラム

数値のリスト nums と整数 diff が与えられたとき、隣り合う要素同士の差がすべて diff と一致するような最長の等差部分列(算術サブシーケンス)の長さを求める問題を考えます。

たとえば、nums = [-1, 1, 4, 7, 2, 10]diff = 3 の場合を考えてみましょう。このとき、部分列 [1, 4, 7, 10] を選ぶことができ、各要素間の差はすべて 3 になるため、答えは 4 となります。

解法のアプローチ

この問題は動的計画法(DP)の考え方を使うと効率的に解けます。各値について「その値で終わる等差部分列の最大長」を辞書に記録しながら、リストを一度走査するだけで答えが求まります。具体的な手順は以下の通りです。

  • seen:各値をキーとし、「その値で終わる等差部分列の長さ」を格納する辞書。キーが存在しない場合のデフォルト値は 0。
  • mx:これまでに見つかった最長の長さ。初期値は 0。
  • リスト内の各要素 x に対して以下を繰り返します。
    • x - diffseen に存在する場合は、seen[x] := seen[x - diff] + 1 とする。
    • 存在しない場合は、seen[x] := 1 とする(その要素単体で長さ 1 の部分列となるため)。
  • mxmxseen[x] の最大値で更新します。
  • 最後に mx を返します。

実装例(Python)

それでは、実際のコード実装を見て理解を深めましょう。

from collections import defaultdict

def solve(nums, diff):
    seen = defaultdict(int)
    mx = 0
    for x in nums:
        if x - diff in seen:
            seen[x] = seen[x - diff] + 1
        else:
            seen[x] = 1
        mx = max(mx, seen[x])
    return mx

nums = [-1, 1, 4, 7, 2, 10]
diff = 3
print(solve(nums, diff))

入力

[-1, 1, 4, 7, 2, 10], 3

出力

4

計算量について

このアルゴリズムはリストを一度だけ走査し、各ステップでの辞書操作は O(1) で行えるため、時間計算量は O(n)、空間計算量も O(n) となります(n はリストの要素数)。素朴な全探索では O(n²) 以上かかるところを、この方法なら線形時間で効率よく解くことができます。

  1. Pythonで最長アナグラム部分列の長さを求めるプログラム

    問題の概要小文字のみで構成された2つの文字列 S と T が与えられたとき、「最も長いアナグラム部分列」の長さを求めます。ここでアナグラム部分列とは、両方の文字列に共通して含まれる文字を組み合わせて作れる、同じ文字構成を持つ部分列のことです。例えば、S = helloworld、T = hellorld の場合、答えは 8 になります。これは、両方の文字列で共有できる文字(h ×1、e ×1、l ×3、o ×1、r ×1、d ×1)の合計が8文字であるためです。解法のアプローチこの問題は、各文字列における文字の出現回数を数え、その最小値を合計することで効率的に解けます。手順は以下の通りです。文

  2. Pythonで最長のバランス括弧部分列の長さを求めるプログラム

    問題概要 文字列 s が与えられます。この文字列には括弧「(」と「)」が含まれており、その中からバランスの取れた(対応関係が成立している)括弧の部分列として最も長いものを見つけ、その長さを返すことが目標です。 たとえば、入力が s = ())(()( の場合、出力は 4 になります。「(」と「)」を選び抜いて ()() というバランスの取れた部分列を作れるためです。 解法のアプローチ この問題は、文字列を後ろから走査することで線形時間で解けます。閉じ括弧を先に確保しておき、開き括弧が出てきたときに対を成立させるという発想です。手順は以下の通りです。 結果を格納する変数 res を 0 で初