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