Pythonで1種類の文字だけを含む部分文字列の総数を求めるプログラム
問題の概要
小文字の英字のみで構成される文字列 s が与えられたとき、「1種類の文字だけで構成されている部分文字列」の総数を求めます。
例えば、入力が "xxyy" の場合、出力は 6 になります。条件を満たす部分文字列は [x, x, xx, y, y, yy] の6つだからです。
解決のアプローチ
この問題は、連続して同じ文字が並ぶ区間(ラン)ごとに考えると効率的に解けます。長さ n の同一文字の連続区間から作れる部分文字列の数は n(n+1)/2 個ですが、ループ内で「現在の文字が何文字連続しているか」をカウントしながら合計へ加算していけば、結果的に同じ値が得られます。
具体的な手順は次のとおりです。
- 合計値 total を 0 で初期化する
- 前回の文字 previous を空文字列で初期化する
- 文字列 s の各文字 c について以下を繰り返す
- c が previous と異なる場合:previous を c に更新し、連続カウント in_a_row を 1 にリセットする
- c が previous と同じ場合:in_a_row を 1 増やす
- いずれの場合も、in_a_row の値を total に加算する
- 最後に total を返す
実装例
class Solution:
def solve(self, s):
total = 0
previous = ''
for c in s:
if c != previous:
previous = c
in_a_row = 1
else:
in_a_row += 1
total += in_a_row
return total
ob = Solution()
print(ob.solve("xxyy"))
入力
"xxyy"
出力
6
処理の流れを確認
入力 "xxyy" の場合、処理は次のように進みます。
- 1文字目 'x':previous と異なるため in_a_row = 1、total = 1
- 2文字目 'x':previous と同じため in_a_row = 2、total = 3
- 3文字目 'y':previous と異なるため in_a_row = 1、total = 4
- 4文字目 'y':previous と同じため in_a_row = 2、total = 6
最終的な total は 6 となります。"xx" の部分からは x・x・xx の3つ、"yy" の部分からは y・y・yy の3つが数えられ、合計6個の部分文字列が正しく検出されています。
計算量
文字列を一度走査するだけなので、時間計算量は O(n)、追加のメモリ使用量は O(1) で済みます。長い文字列に対しても高速に動作するのが特徴です。
-
Pythonで木の特定の辺を含む一意なパスの総数をカウントするプログラム
木構造を表す辺のリスト (u, v) が与えられます。ここで、各辺について「その辺を含む一意なパス(単純パス)」の総数を求め、入力された辺と同じ順序で結果を返す必要があります。例として、入力が edges = [[0, 1], [0, 2], [1, 3], [1, 4]] の場合を考えてみましょう。この場合、出力は [6, 4, 4, 4] となります。解き方のアプローチこの問題は、以下の手順で解くことができます。与えられた辺から隣接リスト adj を作成します。各頂点の部分木サイズを記録するためのマップ count を用意します。関数 dfs(x, parent) を定義します。count
-
【Python】文字列がすべてユニークな文字で構成されているか判定する方法
本記事では、与えられた文字列に含まれる文字がすべて一意(ユニーク)であるかどうかを判定するPythonプログラムについて、その解法とアプローチをわかりやすく解説します。 問題の概要 文字列が入力として与えられたとき、その文字列に含まれるすべての文字が重複なく一意であるかどうかを判定します。たとえば「abcde」はすべて異なる文字で構成されているためTrue、「tutorialspoint」のように同じ文字が複数回出現する場合はFalseとなります。 アプローチ この問題は、以下のような手順で効率的に解くことができます。 ブール値の配列を用意する: 各インデックス i が「アルファベット(AS