Pythonで先頭文字が同じ単語が連続する最長サブリストの長さを求める方法
問題の概要
小文字のアルファベットで構成された文字列のリスト words が与えられたとします。この中から「隣り合う単語の先頭文字がすべて同じである」最も長い連続するサブリスト(部分リスト)を見つけ、その長さを求めるのが今回の課題です。
たとえば、入力が ["she", "sells", "seashells", "on", "the", "sea", "shore"] の場合、出力は 3 になります。最も長い連続サブリストは ["she", "sells", "seashells"] であり、これらの単語の先頭文字はすべて 's' で共通しているためです。
解決のアプローチ
この問題は、リストを一度だけ走査しながら「現在の連続カウント」と「最大カウント」を更新していくシンプルな手法で解けます。手順は以下の通りです。
- カウンタ
cntを 1、最大値maxcntを 0、前回の先頭文字prev_charを空文字列で初期化します。 - リスト内の各単語について、次の処理を繰り返します。
prev_charが空であれば、その単語の先頭文字をprev_charに設定します。prev_charが単語の先頭文字と同じであれば、cntを 1 増やします。- それ以外の場合は、
prev_charを新しい先頭文字に更新し、cntを 1 にリセットします。
- 毎回、
maxcntをmaxcntとcntの大きい方の値で更新します。 - ループ終了後、
maxcntを返します。
Pythonでの実装例
理解を深めるために、実際のコードを見てみましょう。
def solve(words):
cnt = 1
maxcnt = 0
prev_char = ""
for word in words:
if prev_char == "":
prev_char = word[0]
elif prev_char == word[0]:
cnt += 1
else:
prev_char = word[0]
cnt = 1
maxcnt = max(maxcnt, cnt)
return maxcnt
words = ["she", "sells", "seashells", "on", "the", "sea", "shore"]
print(solve(words))
入力
["she", "sells", "seashells", "on", "the", "sea", "shore"]
出力
3
処理の流れをトレースしてみる
入力例に対する各ステップの動きは次のようになります。
"she"→prev_charが空のため's'を設定(cnt=1)"sells"→ 先頭文字が's'で一致し、cnt=2"seashells"→ 同様に一致し、cnt=3(maxcnt=3に更新)"on"→ 先頭文字が'o'に変わり、cnt=1にリセット"the"→ 先頭文字が't'に変わり、cnt=1"sea"→ 先頭文字が's'に変わり、cnt=1"shore"→ 先頭文字が's'で一致し、cnt=2
最終的に記録された最大値 3 が返されます。
計算量
このアルゴリズムはリストを一度だけ走査するため、時間計算量は O(n)(n は単語の数)、追加で必要なメモリは O(1) です。大規模なデータに対しても効率的に動作する、非常にシンプルかつ実用的なアプローチと言えます。
-
Pythonで最大の合計を持つ連続サブリスト(部分配列)の合計を求めるプログラム
配列 A が与えられたとき、「最大の合計を持つ連続した部分リスト(サブアレイ)」を見つけ、その合計値を返すことを考えます。例えば、配列が A = [-2, 1, -3, 4, -1, 2, 1, -5, 4] の場合、答えは合計 6 となり、該当する部分配列は [4, -1, 2, 1] です。解き方:動的計画法(DP)の活用この問題は、動的計画法(Dynamic Programming)を使うことで効率的に解けます。基本的な考え方は、「各位置で終わる部分配列の合計の最大値」を順番に求めていくというものです。配列 A と同じサイズの配列 dp を用意し、すべて 0 で初期化するdp[0] :=
-
Pythonで1つの要素を削除して作れる最長の連続増加サブリストの長さを求める方法
問題の概要 数値のリスト nums が与えられます。ここで、リストから0個または1個の要素を削除できるものとし、その結果として得られる「連続した厳密に増加する部分リスト(サブリスト)」の最大の長さを求めます。 たとえば、入力が nums = [30, 11, 12, 13, 14, 15, 18, 17, 32] の場合、答えは 7 になります。18 を削除すれば [11, 12, 13, 14, 15, 17, 32] という最も長い連続した厳密増加部分リストが得られ、その長さがちょうど 7 になるためです。 解法の考え方 この問題は、次の2つの配列を用意すると効率よく解けます。 pre