Pythonで2つの文字列の順列が辞書式順序の大小関係を満たすかどうかをチェックする方法
問題の概要
同じ長さ n を持つ2つの文字列 s と t が与えられたとき、次の条件を満たすような順列(並べ替え)が存在するかどうかを判定します。
- s のある順列 s1 と t のある順列 t1 について、すべての 0 ≤ i < n に対して s1[i] ≤ t1[i] が成り立つ、または
- すべての 0 ≤ i < n に対して t1[i] ≤ s1[i] が成り立つ
つまり、「どちらか一方の文字列を並べ替えることで、もう一方の文字列に対して各位置で常に小さい(または等しい)状態にできるか」という問題です。
入力例
たとえば、s = "vyx"、t = "wzx" という入力の場合、出力は True になります。実際、s1 = "vxy"、t1 = "wxz" と並べ替えれば、各位置で v ≤ w、x ≤ x、y ≤ z がすべて成り立つためです。
解法のアプローチ
この問題は、両方の文字列をあらかじめソートしておくことで効率的に解けます。手順は以下のとおりです。
- s と t が空文字列の場合は True を返す
- 文字列 s をソートする
- 文字列 t をソートする
- 補助関数 util() を定義する。引数として s1 と t1 を受け取る
- i を 0 から s1 の長さまで繰り返し処理する:
- s1[i] > t1[i] であれば False を返す
- ループを最後まで抜ければ True を返す
- メインの処理では以下を行う:
- util(s, t) が真であれば True を返す
- s と t を入れ替える
- util(s, t) の結果を返す
なぜソートでうまくいくのか?
ある並べ替えによって「各位置で片方がもう片方以下」という関係が成立するなら、両方の文字列を昇順にソートした場合にも必ず同じ関係が成立します。ソートされた状態は最も整列した配置であり、大小比較が最も有利になるためです。したがって、順列の全パターンを試す必要はなく、ソート後の文字列同士を比較するだけで答えが分かります。計算量は O(n log n) に抑えられます。
Pythonでの実装例
class Solution:
def solve(self, s, t):
if not len(s) or not len(t):
return True
s = sorted(s)
t = sorted(t)
def util(s1, t1):
for i in range(len(s1)):
if s1[i] > t1[i]:
return False
return True
if util(s, t):
return True
s, t = t, s
return util(s, t)
ob = Solution()
s = "vyx"
t = "wzx"
print(ob.solve(s, t))
入力
"vyx", "wzx"
出力
True
まとめ
この問題の鍵は「ソートすれば十分である」という性質に気づくことです。Pythonの sorted() を使って両方の文字列を昇順に並べ替え、要素ごとの比較を一度行い、成立しなければ文字列を入れ替えて再度比較するだけで、O(n log n) の計算量で答えを求められます。全順列を総当たりする非現実的な手法と比べて、非常にシンプルかつ高速な解法といえます。
-
C言語で2つの文字列が同じかどうかを判定するプログラムの作成方法
2つの文字列 str1 と str2 が与えられたとき、その2つが同じ文字列であるかどうかを判定します。例えば「hello」と「hello」のように、まったく同一の文字列であれば「同じ」とみなされます。 「見た目が似ている文字列」と「完全に一致する文字列」の違い 「Hello」と「hello」のように、一見すると同じように見えても大文字と小文字が異なるため、実際には等しくない文字列があります。これに対して、「World」と「World」のように1文字たりとも違わず完全に一致する場合のみ、「同じ文字列」として扱われます。 例 入力: str1[] = {Hello}, str2[] = {Hel
-
【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の組