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

【Python】文字の入れ替え操作で2つの文字列を一致させられるか判定する方法

問題の概要

同じ長さの小文字のみで構成された2つの文字列 st が与えられます。s から1文字、t から1文字を選んで入れ替える(スワップする)操作を、好きな回数だけ繰り返せるとします。このとき、2つの文字列を完全に同じにできるかどうかを判定するのが本記事のテーマです。

例えば、入力が s = "abcd"、t = "cdab" の場合、出力は True になります。

解法のアプローチ

この問題は、以下の手順で解くことができます。

  • s と t を連結した文字列に含まれる各文字の出現回数(fre)を集計します。
  • fre の各値(cnt)について次を確認します。
    • cnt を2で割った余りが1(つまり奇数)の場合は False を返します。
  • すべての文字数が偶数であれば、True を返します。

なぜこれで判定できるのか

ポイントは「スワップ操作を何度行っても、全体としての文字の出現頻度は変わらない」という点です。ある文字の合計出現回数が偶数であれば、その文字を s 側と t 側にちょうど半分ずつ振り分けられるため、両者を一致させることが可能です。逆に、たった一つの文字でも奇数回出現していれば、2つの文字列を完全に一致させることはできません。

実装例

Python の標準ライブラリ collections.Counter を使えば、文字ごとの出現回数を簡単に集計できます。以下が実際のコードです。

from collections import Counter

def solve(s, t):
    fre = Counter(s + t)

    for cnt in fre.values():
        if cnt % 2:
            return False

    return True

s = "abcd"
t = "cdab"
print(solve(s, t))

入力

"abcd", "cdab"

出力

True

計算量について

時間計算量は O(n)(n は文字列の長さ)です。Counter の構築に文字列の長さに比例した時間がかかりますが、小文字は最大26種類しかないため、頻度チェックのループ部分は定数時間とみなせます。空間計算量も O(n) であり、非常に効率的な解法といえます。

  1. Pythonで左右の部分木の入れ替えにより2つの二分木を一致させられるか判定する方法

    問題の概要 2つの二分木が与えられたとき、任意のノードについて左部分木と右部分木を何度でも入れ替えてよいと仮定します。この操作を繰り返すことで、1つ目の木を2つ目の木とまったく同じ形に変換できるかどうかを判定するのが、この記事で扱う問題です。 例えば、次のような2つの木が入力として与えられた場合、左右の入れ替えによって一致させられるため、出力は True になります。 解決のアプローチ この問題は、幅優先探索(BFS)の考え方を使い、木をレベル(深さ)ごとに処理しながらノードの値を比較することで解けます。左右の入れ替えによって同じレベル内の値の並び順は反転し得るため、「順方向」または「逆方

  2. Pythonで文字を入れ替えて、同じ長さの2つの文字列を等しくできるか判定する方法

    問題の概要長さnの2つの文字列 s と t があるとします。s から1文字、t から1文字を選んで入れ替える(スワップする)操作は何度でも行えます。このとき、2つの文字列を完全に等しくすることが可能かどうかを判定するのが課題です。例えば、入力が s = xy、t = yx の場合、出力は True になります。解法のアプローチこの問題は、次の手順で解くことができます。s と t を連結した文字列 st を作成し、ソートします。st の先頭から2文字ずつペアとして確認します(インデックス0から開始し、2ずつ増やしながらループ)。st[i] と st[i+1] が異なる場合は、False を返しま