Python
 Computer >> コンピューター >  >> プログラミング >> Python

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) となり、単語数が多い場合に非効率になります。ワイルドカードパターンとセットを組み合わせることで、大幅な高速化が実現できるのがこの手法のポイントです。

  1. 【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の組

  2. Pythonで2つの二分木の葉の並び(シーケンス)が同じかどうかを確認する方法

    はじめに2つの二分木が与えられたとき、それぞれの木を左から右へたどったときの葉ノードの並び(シーケンス)が一致しているかどうかを判定する問題を考えてみましょう。例えば、次のような2つの木が入力として与えられた場合を想定します。この場合、どちらの木も葉の並びは [2, 6] となるため、出力は True になります。解決のアプローチこの問題を解くためには、以下の手順に従います。結果を格納するための新しいリスト c を用意します。inorder() 関数を定義します。この関数はルートノードとリスト c を引数に取ります。c が null の場合は、新しい空のリストを作成します。ルートノードが nu