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

Pythonでi個のx、j個のy、k個のzからなる部分列の個数を求めるプログラム

文字列 s が「x」「y」「z」で構成されているとします。このとき、「x」が i 個(i ≥ 1)、その後に「y」が j 個(j ≥ 1)、さらにその後に「z」が k 個(k ≥ 1)という順序で並ぶ部分列の総数を求めます。

例えば、入力が s = "xxyz" の場合、出力は 3 になります。これは "xyz" を2通りと "xxyz" を1通りの合計3通り作れるためです。

解き方のアプローチ

この問題は動的計画法(DP)の考え方を使うと効率的に解けます。文字列を先頭から順に走査しながら、次の3つのカウンターを更新していきます。

  • x: それまでに見つかった「xのみで構成される部分列」の個数
  • y: それまでに見つかった「x…xy…y」という形式の部分列の個数
  • z: それまでに見つかった「x…xy…yz…z」という形式の部分列の個数

更新ルール

各文字を読み込んだときの更新式は以下の通りです。

  • s[i] が "x" の場合:x = x * 2 + 1(既存のx部分列に新しいxを付け足すか、そこで新しく部分列を始めるかの2択があるため)
  • s[i] が "y" の場合:y = y * 2 + x(既存のy部分列を延長するか、これまでのx部分列にyを接続するか)
  • s[i] が "z" の場合:z = z * 2 + y(既存のz部分列を延長するか、これまでのy部分列にzを接続するか)

最終的な答えは z の値となります。

Pythonコード例

class Solution:
    def solve(self, s):
        n = len(s)

        x = 0
        y = 0
        z = 0
        for i in range(n):
            if s[i] == "x":
                x *= 2
                x += 1
            if s[i] == "y":
                y *= 2
                y += x
            if s[i] == "z":
                z *= 2
                z += y

        return z

ob = Solution()
print(ob.solve("xxyz"))

入力

"xxyz"

出力

3

計算量について

このアルゴリズムは文字列を一度だけ走査するため、時間計算量は O(n)、追加で必要なメモリは O(1) で済みます。文字列が非常に長い場合でも高速に動作するのが大きな利点です。

  1. PythonでビットごとANDとORの合計が最大になる部分列の組み合わせを求める方法

    問題の概要 n個の要素からなる配列が与えられたとき、その配列から2つの部分列を選びます(2つの部分列は同じものでも異なるものでも構いません)。そして、1つ目の部分列の全要素のビットごとのAND(論理積)の値と、2つ目の部分列の全要素のビットごとのOR(論理和)の値を足し合わせた合計が最大になるようにします。 例えば、入力が A = {4, 6, 7, 2} の場合、出力は 14 になります。これは、要素「7」だけを選ぶことで最大のAND値である7が得られ、すべての要素(4 | 6 | 7 | 2)= 7 を選ぶことで最大のOR値である7が得られるためです。したがって、結果は 7 + 7 = 1

  2. Pythonでリスト内の最大値を見つける方法|sort()とmax()の2つのアプローチ

    この記事では、リストの中から最大の数値を見つけるための解決策とアプローチについて詳しく解説します。問題の概要数値のリストが与えられたとき、その中から最大の要素を見つけ出す必要があります。Pythonでは、主に以下の2つの方法でこれを実現できます。ソート(並べ替え)を利用する方法組み込み関数 max() を利用する方法アプローチ1:sort() 関数を使う方法リストを sort() メソッドで昇順に並べ替えると、リストの最後の要素(インデックス -1)が必ず最大値になります。サンプルコードlist1 = [18, 65, 78, 89, 90] list1.sort() # メイン処理 prin