Pythonで最大k種類の異なる文字を含む最長部分文字列の長さを求める方法
数値 k と文字列 s が与えられたとき、最大で k 種類の異なる文字を含む最長の部分文字列(substring)の長さを求める問題について解説します。
例えば、k = 3、s = "kolkata" が入力として与えられた場合、出力は 4 になります。これは、「kolk」と「kata」という2つの部分文字列がどちらも3種類の異なる文字を含み、その長さが4であるためです。
解法のアプローチ:スライディングウィンドウ
この問題は「スライディングウィンドウ(sliding window)」という手法を使うことで効率的に解けます。ウィンドウの右端を1つずつ進めながら、ウィンドウ内に含まれる異なる文字の種類数をハッシュマップ(辞書)で管理し、種類数が k を超えた場合には左端を縮めて調整していくのが基本的な考え方です。
アルゴリズムの手順
- 答えを格納する
ansとウィンドウ左端のleftを 0 で初期化します。 - 各文字の出現回数を記録するマップ
tableを作成します。 rightを 0 から文字列の長さ - 1 まで順に処理します。table[s[right]]のカウントを 1 増やします(キーが存在しない場合は 0 からスタート)。- マップのサイズ(異なる文字の種類数)が
k以下であれば、ansと現在のウィンドウ幅(right - left + 1)の大きい方でansを更新します。 - それ以外の場合は、マップのサイズが
k以下になるまで左端を縮め続けます。left_char = s[left]を取得します。table[left_char]が 1 であれば、そのキーをマップから削除します。- そうでなければ、
table[left_char]を 1 減らします。 leftを 1 増やします。
- 最後に
ansを返します。
実装例
以下がPythonでの実装例です。
class Solution:
def solve(self, k, s):
ans = 0
left = 0
table = {}
for right in range(0, len(s)):
table[s[right]] = table.get(s[right], 0) + 1
if len(table) <= k:
ans = max(ans, right - left + 1)
else:
while len(table) > k:
left_char = s[left]
if table[left_char] == 1:
table.pop(left_char)
else:
table[left_char] -= 1
left += 1
return ans
ob = Solution()
k = 3
s = "kolkata"
print(ob.solve(k, s))
入力
k = 3, s = "kolkata"
出力
4
計算量について
このアルゴリズムの時間計算量は O(n) です。右端 right は文字列を一度だけ走査し、左端 left も後戻りせず前進するだけなので、全体を線形時間で処理できます。空間計算量は、マップに保持される文字の種類数に依存し、最大でも O(k) 程度に抑えられます。
-
Pythonで最長アナグラム部分列の長さを求めるプログラム
問題の概要小文字のみで構成された2つの文字列 S と T が与えられたとき、「最も長いアナグラム部分列」の長さを求めます。ここでアナグラム部分列とは、両方の文字列に共通して含まれる文字を組み合わせて作れる、同じ文字構成を持つ部分列のことです。例えば、S = helloworld、T = hellorld の場合、答えは 8 になります。これは、両方の文字列で共有できる文字(h ×1、e ×1、l ×3、o ×1、r ×1、d ×1)の合計が8文字であるためです。解法のアプローチこの問題は、各文字列における文字の出現回数を数え、その最小値を合計することで効率的に解けます。手順は以下の通りです。文
-
Pythonで同じ文字が連続する最長部分文字列の長さを求めるプログラム
この記事では、Pythonを使って「同じ文字が連続している最長の部分文字列の長さ」を求める方法を解説します。 例えば、入力が abbbaccabbbba の場合、b が4つ連続して並んでいる箇所があるため、出力は 4 となります。 解法のアプローチ この問題は、文字列を先頭から順番に走査し、隣接する2つの文字を比較することで解決できます。具体的な手順は以下のとおりです。 文字列 s の長さが 0 の場合は、そのまま 0 を返します。 s の末尾に空白文字を1つ追加します。これは、ループ処理の際に文字列の最後にある連続グループも確実に確定させるためのテクニックです。 カウンター ct と一時