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

Pythonで最長の減少単語チェーンの長さを求めるプログラム

有効な単語のリストと文字列 s が与えられたとき、s から始めて1文字ずつ削除しながら、その各段階でも有効な単語になるように辿れる「減少単語チェーン」のうち、最も長いものの長さを求める問題です。

たとえば、入力が words = ["lii", "limit", "limi", "li", "coffee", "jug", "pool", "type"]、s = "limit" の場合、出力は 4 になります。これは「limit」を出発点として、「limit」→「limi」→「lii」→「li」というチェーンが作れるためです。

解き方のアプローチ

この問題は再帰呼び出しを使うことでシンプルに解けます。基本的な流れは以下のとおりです。

  • solve() 関数を定義します。引数として words と s を受け取ります。
  • max_num := 0 で初期化します。
  • words 内の各単語 i について次を繰り返します。
    • i が s と一致する場合、j を 0 から s の長さまで動かしながら、j 番目の文字を取り除いた新しい文字列に対して solve() を再帰的に呼び出し、「1 + 戻り値」と現在の max_num の大きい方を max_num に代入します。
  • 最後に max_num を返します。

Pythonでの実装例

class Solution:
   def solve(self, words, s):
      max_num = 0
      for i in words:
         if i == s:
            for j in range(len(s)):
               max_num = max(1 + self.solve(words, s[:j] + s[j + 1 :]), max_num)
      return max_num

ob = Solution()
words = ["lii", "limit", "limi", "li", "coffee", "jug", "pool", "type"]
s = "limit"
print(ob.solve(words, s))

入力

["lii", "limit", "limi", "li", "coffee", "jug", "pool", "type"],"limit"

出力

4

アルゴリズムのポイント

このコードでは、現在の文字列 s が単語リストに含まれているかどうかを毎回確認しています。一致する単語が見つかった場合は、すべての位置について1文字を削除した文字列を生成し、それに対して再帰的に同じ処理を適用します。一致する単語が存在しない状態では max_num が 0 のまま返されるため、チェーンが途切れた時点で探索が自動的に打ち切られます。

なお、単語数や文字列の長さが大きくなると計算量が急増します。その場合は functools.lru_cache などでメモ化を行うことで、同じ文字列に対する重複計算を避け、処理を大幅に高速化できます。

  1. Pythonで「a」から始まる連続増加部分文字列の最長長さを求めるプログラム

    問題の概要小文字の英字と「?」記号を含む文字列 s が与えられます。各「?」については、削除するか、任意の小文字の英字に置き換えることができます。このとき、「a」で始まる連続して増加する部分文字列(例:abcdef のようにアルファベット順に1文字ずつ進む文字列)の最長の長さを求める必要があります。例えば、入力が s = vta???defke の場合、出力は 6 になります。これは、s を vtabcdefke に変換できるためです。変換後の文字列には abcdef という連続増加部分文字列が含まれており、これが「a」で始まる最長のものとなります。解法のアプローチこの問題は、文字列を一度走査

  2. Pythonでn分木の最長パスの長さを求めるプログラムの書き方

    各要素が (u, v) という形式を持ち、u が v の親であることを表す辺リストが与えられているとします。このとき、木の中で最も長いパスの長さを求める必要があります。ここでいうパスの長さとは、「そのパスに含まれるノードの総数 + 1」のことです。 たとえば、入力が下図のような n 分木だった場合を考えてみましょう。 この場合の出力は 5 になります。なぜなら、パス [1, 4, 5, 7] には合計 4 つのノードが含まれており、パスの長さは 1 + 4 = 5 となるからです。 解き方のアプローチ この問題は、幅優先探索(BFS)を2回実行するという定番テクニックで効率よく解けます。まず