長さを決めた窓で並べ替えた言葉が文の中に続けて入っているか調べる

言葉 p の文字を並べ替えた物が、文 s の中に途切れずに入っているかを調べます。p と同じ長さの窓を 1 文字ずつずらし、窓の中の文字の数を足し引きして比べる、長さを決めたスライディングウィンドウの練習です。

海外で定番の問題リスト 4 本には入っていません

問題

英小文字だけの言葉 p と、英小文字だけの文 s を受け取ります。p の文字を並べ替えてできる言葉 (並べ替えないそのままも含む) のどれかが、s の中に途切れずに入っていれば true、入っていなければ false を返す関数を書いてください。

  • 並べ替えでは、文字の種類と数をそのまま使います。同じ文字が 2 つあれば、2 つとも使います
  • s の中で飛び飛びに拾った文字は数えません。続いた部分だけを見ます
  • p と s の長さは、どちらも 1 以上 10000 以下です。p が s より長いこともあります

入力と出力の例

例 1

s の左から 4 文字目からの "eat" は、"tea" の文字を並べ替えた言葉です。

p = "tea" s = "greateagle"
true

例 2

s に a も b もありますが、あいだに x がはさまっていて、続いた 2 文字の a と b がありません。

p = "ab" s = "axb"
false

例 3

a が 2 つの言葉です。s の "baa" は、a が 2 つと b が 1 つで、数まで合っています。

p = "aab" s = "xbaay"
true

面接での聞かれ方

面接では、アナグラムや並べ替えの言葉で渡されることがよくあります。

  • 「s が、p の並べ替えのどれかを部分文字列として含むか判定してください」
  • 「文字は英小文字だけですか?」と、自分から確かめるかを見られます
  • 書き終えたあとに「1 回ずらすたびに 26 文字を比べずに済みませんか?」と広げられることもあります

並べ替えを全部作ると、長さ 10 の言葉でも 360 万通りを超えます。並べ替えを作らずに「文字の種類と数が同じか」で比べる、と気づくのが入口です。

ヒント

まだ開いていません

付箋は 4 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

アルゴリズムのチートシートの「配列と文字列」に、この型の要点を表とコードでまとめています。

配列と文字列の問題は、全部の組を調べると手間が大きくなる所を、窓や左右の添字で減らす形が多いです。

main.py
def has_shuffled(p: str, s: str) -> bool:
    """
    Goal: 何を返すか

    idea1: まず思いつく案
    -> runtime: O(?)  space: O(?)

    idea2: もっと速い案
    -> runtime: O(?)  space: O(?)

    edge case: 空、1 つだけ、など
    """
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(has_shuffled("tea", "greateagle"))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します