Pythonでk個の連続する重複文字を削除した後の文字列を求めるプログラム
文字列 s と整数 k が与えられたとき、「同じ文字が k 個連続している部分」を繰り返し削除していき、最終的に残る文字列を求める問題を考えます。
例えば、入力が s = "paaappmmmma"、k = 3 の場合、出力は "ma" になります。処理の流れは以下のとおりです。
- まず連続する3つの "a" を削除 → "pppmmmma"
- 次に連続する3つの "p" を削除 → "mmmma"
- 最後に4つある "m" のうち連続する3つを削除 → "ma"
解き方のアプローチ
この問題は、次の手順で解くことができます。
- 以下の処理を、変更がなくなるまで繰り返します。
countを 0 で初期化するsに含まれる一意な文字の集合charsを取得するcharsの各文字cについて、次を行うcがk個連続した部分文字列がsに存在する場合は、それを削除し、countを 1 増やす
countが 0 のままなら、これ以上削除できる箇所がないためループを抜ける
- 最終的な
sを返す
実装例
理解を深めるために、以下のPythonコードを見てみましょう。
class Solution:
def solve(self, s, k):
while True:
count = 0
chars = set(s)
for c in chars:
if c * k in s:
s = s.replace(c * k, "")
count += 1
if count == 0:
break
return s
ob = Solution()
s = "paaappmmmma"
k = 3
print(ob.solve(s, k))
入力
"paaappmmmma", 3
出力
ma
計算量の改善:スタックを使った O(n) の解法
上記の素朴な実装では、削除がなくなるまで文字列全体を何度も走査するため、文字列が長い場合には非効率になる可能性があります。スタックを使えば、文字列を一度だけ走査する O(n) の計算量で同じ結果を得られます。
class Solution:
def solve(self, s, k):
stack = [] # [文字, 連続数] のペアを管理
for ch in s:
if stack and stack[-1][0] == ch:
stack[-1][1] += 1
if stack[-1][1] == k:
stack.pop()
else:
stack.append([ch, 1])
return ''.join(ch * cnt for ch, cnt in stack)
ob = Solution()
s = "paaappmmmma"
k = 3
print(ob.solve(s, k))
この方法では、各文字について「直前の文字と同じかどうか」と「連続数が k に達したか」を確認するだけでよいため、大きな入力に対しても高速に動作します。連続数が k に達した時点でそのグループをスタックから取り除くことで、削除をその場で完了できるのがポイントです。
-
Pythonで文字列内のミラー文字を検索する方法【初心者向け解説】
ユーザーが入力した文字列と位置(ポジション)が与えられたとき、その位置から文字列の末尾までの文字を、アルファベット順を反転させた「ミラー文字」に変換するプログラムを作成します。この操作では、「a」→「z」、「b」→「y」、「c」→「x」、「d」→「w」のように、アルファベットの最初の文字が最後の文字に対応する形で置き換えを行います。 入力: p = 3 入力文字列 = python 出力: pygslm 上記の例では、3番目の位置以降の文字「t」「h」「o」「n」が、それぞれ逆順のアルファベット「g」「s」「l」「m」に変換されていることがわかります。先頭から指定位置までは元の文字列
-
Pythonを使って文字列内の重複文字をすべて検出する方法
文字列がひとつ与えられます。ここでの課題は、その文字列の中から出現回数が2回以上の文字(重複文字)をすべて見つけ出すことです。 たとえば「Hello World. Lets learn Python」という文字列を例にすると、アルゴリズムは複数回出現している文字を検出します。この場合の出力は次のようになります。 e : 3 l : 4 o : 3 <空白> : 4 r : 2 t : 2 n : 2 この問題を実装するには、Pythonのcollectionsモジュールを使用します。collectionsからはCounter()クラスを利用できます。Counter()はハッシ