Pythonで2つの同一文字の間に挟まれた最長部分文字列を求めるプログラム
文字列 s が与えられたとき、同じ文字2つに挟まれた部分文字列のうち、両端の2文字を除いた部分の最大の長さを求める問題を考えます。該当する部分文字列が存在しない場合は、-1 を返します。
例えば、s = "level" の場合、出力は 3 になります。これは、先頭と末尾の "l" の間に "eve"(長さ3)が挟まれているためです。
解法のアプローチ
この問題は、各文字の出現位置を記録し、同じ文字の最初の出現位置と最後の出現位置の差を調べることで効率的に解けます。手順は以下の通りです。
- memo := 新しいマップ(辞書)を作成する
- i を 0 から s のサイズ - 1 まで繰り返す:
- s[i] が memo に存在する場合は、memo[s[i]] の末尾に i を追加する
- 存在しない場合は、memo[s[i]] := 要素 i のみを持つリストを作成する
- best := 0 で初期化する
- memo の各キーについて、best := max(best, memo[key] の最後の要素 − memo[key] の最初の要素) を計算する
- best - 1 を返す
Pythonでの実装例
def solve(s):
memo = {}
for i in range(len(s)):
if s[i] in memo:
memo[s[i]].append(i)
else:
memo[s[i]] = [i]
best = 0
for key in memo:
best = max(best, memo[key][-1] - memo[key][0])
return best - 1
s = "level"
print(solve(s))入力
"level"
出力
3
アルゴリズムのポイント
このアルゴリズムの計算量は、時間・空間ともに O(n)(n は文字列の長さ)です。同じ文字の間隔が最大になるのは必ず最初の出現位置と最後の出現位置の組み合わせであるため、それぞれの文字についてこの2点だけを比較すれば十分です。
また、すべての文字が1回しか出現しない場合、best は 0 のままになるため、best - 1 = -1 が返されます。これにより、「該当する部分文字列が存在しない場合は -1 を返す」という条件も正しく処理されます。
-
Pythonで2つのリストのデカルト積(直積)を求める方法
2つのデータリスト l1 と l2 が与えられたとき、これらのデカルト積(直積)を求めることを考えます。デカルト積とは、2つのリストの要素をすべて組み合わせたペアの集合のことです。例えば、リストが (a, b) と (c, d) の場合、デカルト積は {(a, c), (a, d), (b, c), (b, d)} のようになります。 Pythonでは、標準ライブラリの itertools モジュールに含まれる product() 関数を使うことで、この処理を非常に簡単に実装できます。product() 関数はイテレータを返すため、list() コンストラクタに渡してリスト形式に変換する必要が
-
Pythonで二分木の2つのノード間の距離を求めるプログラム
二分木が与えられたとき、その中の2つのノード間の距離を求めることを考えます。グラフの場合と同じように、2つのノードを結ぶ経路上の辺(エッジ)の数を数え、その本数を距離として返します。 二分木のノード構造 木の各ノードは、次のような構造を持っています。 data : <整数値> right : <木の別のノードへのポインタ> left : <木の別のノードへのポインタ> 問題の例 例として、次のような二分木を考えてみましょう。 この木において、ノード「2」とノード「8」の間の距離を求めたいとします。このときの出力は 4 になります。 ノード2からノード8へ至