Pythonで文字列中の回文部分文字列の数を数える方法
問題の概要
ある文字列が与えられたとき、その文字列に含まれる回文(パリンドローム)部分文字列がいくつあるかを数える問題を考えてみましょう。
ここで重要なのは、開始インデックスまたは終了インデックスが異なる部分文字列は、たとえ同じ文字列で構成されていても別々の部分文字列として数えるという点です。
例えば、入力が "aaa" の場合、出力は 6 になります。これは「a」「a」「a」「aa」「aa」「aaa」という6つの回文部分文字列が存在するためです。
解決のアプローチ
この問題は、以下の手順に従って解くことができます。
- カウンターを 0 で初期化します。
- i を 0 から文字列の長さまで繰り返します。
- j を i + 1 から文字列の長さ + 1 まで繰り返します。
- インデックス i から j までの部分文字列を temp として取り出します。
- temp が回文であれば、カウンターを 1 増やします。
- j を i + 1 から文字列の長さ + 1 まで繰り返します。
- 最後にカウンターの値を返します。
Pythonでの実装例
それでは、実際のコードを見て理解を深めましょう。
class Solution:
def countSubstrings(self, s):
counter = 0
for i in range(len(s)):
for j in range(i+1, len(s)+1):
temp = s[i:j]
if temp == temp[::-1]:
counter += 1
return counter
ob1 = Solution()
print(ob1.countSubstrings("aaaa"))入力
"aaaa"
出力
10
コードのポイント
s[i:j]によって、開始位置 i から終了位置 j までのすべての部分文字列を効率的に取り出しています。temp[::-1]はスライス記法を使った文字列の反転です。元の文字列と反転した文字列が一致すれば、それは回文であると判定できます。- 二重ループにより、すべての開始位置・終了位置の組み合わせを網羅的にチェックしているため、同じ文字でも位置が異なれば別々にカウントされます。
計算量について
この実装はシンプルで分かりやすい反面、計算量は O(n³) になります(部分文字列の組み合わせが O(n²)、各回文判定に O(n) かかるため)。文字列が長くなる場合は、中心拡張法(O(n²))や Manacher のアルゴリズム(O(n))などのより効率的な手法も検討するとよいでしょう。
-
Pythonで文字列を逆順に反転する方法|追加メモリ不要のインプレース手法
文字の配列が与えられたとき、追加のメモリ領域を使用せずに文字列を逆順に反転することを考えます。たとえば、入力が [H, E, L, L, O] である場合、期待される出力は [O, L, L, E, H] となります。 解法のアプローチ この問題は「Two Pointers(ツーポインタ)」と呼ばれる定番のテクニックで効率的に解けます。考え方はシンプルで、配列の両端から中央に向かって文字を交換していくだけです。 手順 2つのポインタを用意します:start = 0、end = 文字列の長さ - 1 s[start] と s[end] の文字を入れ替えます start を1つ増やし、end を
-
Pythonのcasefold()メソッドとは?文字列の小文字変換と比較方法を解説
Pythonのcasefold()は、文字列内の英字をすべて小文字に変換するためのメソッドです。lower()と似ていますが、より積極的な変換を行う点が特徴で、ドイツ語の「ß」が「ss」に変換されるなど、国際化対応において強力な働きをします。2つの文字列に対してcasefold()を適用すれば、大文字・小文字の違いを無視して値を一致させることができます。そのため、ユーザー入力の比較や検索処理などで非常に役立ちます。casefold()の基本的な使い方次の例では、文字列にcasefold()を適用し、すべて小文字に変換された結果を出力しています。コード例string = BestTutorial