Pythonで単語リスト内の異なる回転グループの数を求めるプログラム
問題の概要
文字列には、そのすべての一意な回転をまとめた「回転グループ」が存在するとします。たとえば入力が "567" の場合、この文字列は "675" や "756" に回転でき、これらはすべて同じ回転グループに属します。
ここで、文字列のリスト words が与えられたとき、各単語を回転グループごとに分類し、グループの総数を求める必要があります。
たとえば、words = ["xyz", "ab", "ba", "c", "yzx"] の場合、出力は 3 になります。これは次の3つの回転グループが存在するためです。
["xyz", "yzx"]["ab", "ba"]["c"]
解法のアプローチ
この問題を解くために、以下の手順に従います。
s: 新しい集合(セット)を作成しますct: カウンターを 0 で初期化しますwords内の各要素iについて、以下を処理します:iが集合sに含まれていない場合は、ctを 1 増やしますjを 0 からiの長さまで繰り返し、以下を実行します:temp:=iのインデックスjから末尾までの部分文字列と、先頭からjまでの部分文字列を連結したものtempを集合sに追加します
- 最後に
ctを返します
つまり、各単語から生成されるすべての回転パターンをあらかじめ集合に登録しておき、まだ登録されていない単語が出てきたタイミングでのみカウントを増やすことで、同一の回転グループに属する重複を効率よく除外できます。
実装例
理解を深めるために、以下のPythonコードを見てみましょう。
class Solution: def solve(self, words): s=set() ct=0 for i in words: if i not in s: ct+=1 for j in range(len(i)): s.add(i[j:]+i[:j]) return ct ob = Solution() print(ob.solve(["xyz", "ab", "ba", "c", "yzx"]))
入力
["xyz", "ab", "ba", "c", "yzx"]
出力
3
計算量について
各単語の長さを L、単語の総数を N とすると、すべての回転パターンを生成して集合へ追加する処理の時間計算量は O(N × L²) となります。また、保存された回転パターンの分だけ空間計算量も必要です。それでも、すべての単語ペアを直接比較する方法(O(N² × L))よりも効率的にグループ数を判定できる点が、この手法の大きな利点です。
-
Pythonでリストの累積和(累積合計)を求める方法
この記事では、リストの累積和(累積合計)を求める問題の解決策について詳しく解説します。問題文あるリストが与えられたとき、各要素までの累積和を格納した新しいリストを作成する必要があります。例えば、[10, 20, 30, 40, 50] というリストが与えられた場合、出力は [10, 30, 60, 100, 150] となります。これは、各位置でそれ以前の要素をすべて足し合わせた値です。実装例それでは、実際の実装を見ていきましょう。# 累積和を求める関数 def Cumulative(l): new = [] cumsum = 0 for element in l:
-
Pythonでアナグラム部分文字列検索プログラムを作成する方法
はじめに この記事では、以下の問題文に対する解決策について学びます。 問題文 − テキストとパターンが与えられたとき、テキスト内に含まれるパターンおよびその順列(アナグラム)の出現位置をすべて出力します。 例えば、テキストが「TUTORIALSPOINT」、パターンが「TOR」であれば、「ROT」や「OTR」といった並べ替えも検索対象となります。 アルゴリズムの考え方 この問題は、スライディングウィンドウ(滑動窓)と文字カウント配列を組み合わせることで効率的に解くことができます。手順は以下のとおりです。 パターン内の各文字の出現回数を、カウント配列 countP に記録します。 テキストの先