Pythonで1文字だけ異なる単語のペアが存在するかどうかを判定するプログラム
問題概要
すべて同じ長さの小文字文字列からなるリスト words が与えられたとします。このリストの中に、1文字だけが異なる2つの文字列が存在するかどうかを判定するのが今回の課題です。
例えば、入力が words = ["seed", "pick", "lick", "root", "live"] の場合、「pick」と「lick」は先頭以外の文字が完全に一致しており、1文字だけ異なるため、出力は True になります。
解決アプローチ
この問題は、各単語から1文字をワイルドカード「*」に置き換えたパターンを生成し、そのパターンがすでに登録済みかどうかを確認することで効率的に解決できます。手順は以下の通りです。
- 空のセット
sを用意する words内の各wordについて処理を行う:- 各インデックス
iと文字wに対して:word[:i] + "*" + word[i+1:]というパターンがsに既に存在すればTrueを返す- 存在しない場合は、そのパターンを
sに追加する
- 各インデックス
- ループが完了しても見つからなければ
Falseを返す
実装例
それでは、実際のコードを見てみましょう。
def solve(words):
s = set()
for word in words:
for i, w in enumerate(word):
if word[:i] + "*" + word[i + 1 :] in s:
return True
else:
s.add(word[:i] + "*" + word[i + 1 :])
return False
words = ["seed", "pick", "lick", "root", "live"]
print(solve(words))入力
["seed", "pick", "lick", "root", "live"]
出力
True
計算量について
このアルゴリズムの時間計算量は O(n × m²) です(ここで n は単語数、m は各単語の長さ)。各単語ごとに m 個のパターンを生成し、パターンの作成やセットへの検索・追加にそれぞれ O(m) かかるためです。
もしすべての単語ペアを直接比較する方式を採ると、計算量は O(n² × m) となり、単語数が多い場合に非効率になります。ワイルドカードパターンとセットを組み合わせることで、大幅な高速化が実現できるのがこの手法のポイントです。
-
【Python】グラフ内の2つのノードに共通して到達可能なノードが存在するかを判定するプログラム
問題概要 有向グラフのエッジリストが与えられます。グラフは n 個のノードから構成され、ノード名は 0 から n-1 までです。さらに、2つの整数値 a と b が与えられます。ここで、「あるノード c から a への経路と、c から b への経路がどちらも存在する」という条件を満たすノード c が存在するかどうかを判定するのが課題です。 例として、下図のようなグラフを考えてみましょう。 a = 2、b = 3 の場合、出力は True になります。これは c = 0 とおくと、0 から 2 への経路と 0 から 3 への経路がどちらも存在するためです。 解法の考え方:逆グラフとDFSの組
-
Pythonで2つの二分木の葉の並び(シーケンス)が同じかどうかを確認する方法
はじめに2つの二分木が与えられたとき、それぞれの木を左から右へたどったときの葉ノードの並び(シーケンス)が一致しているかどうかを判定する問題を考えてみましょう。例えば、次のような2つの木が入力として与えられた場合を想定します。この場合、どちらの木も葉の並びは [2, 6] となるため、出力は True になります。解決のアプローチこの問題を解くためには、以下の手順に従います。結果を格納するための新しいリスト c を用意します。inorder() 関数を定義します。この関数はルートノードとリスト c を引数に取ります。c が null の場合は、新しい空のリストを作成します。ルートノードが nu