動的計画法で 2 つの文字列を順を保って混ぜると 3 つ目になるか調べる

2 つの文字列の文字を、それぞれの順を変えずに交互に混ぜて 3 つ目の文字列が作れるかを確かめます。2 つの文字列から使った文字数を表の縦と横に取り、作れる所を埋めていく練習です。

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

問題

文字列 a、b、c を受け取ります。a と b の文字を全部 1 回ずつ使い、a の中の順と b の中の順を変えずに 1 本に混ぜて、c ができるかを返す関数を書いてください。

  • 混ぜ方は自由です。a から何文字か続けて取り、次に b から何文字か取る、をどんな順で繰り返してもかまいません
  • a と b の文字は全部使います。c の長さが a と b の長さの和と違えば false です
  • a と b の長さは 0 以上 100 以下、c の長さは 0 以上 200 以下で、英小文字だけです

入力と出力の例

例 1

a の a、b の x、a の b、b の y、a の c の順に取れば c になります。

a = "abc" b = "xy" c = "axbyc"
true

例 2

先頭の a を 2 つとも a から取ると、残りの b の ab では ba が作れません。1 つ目を a から、次の a と b を b から、最後の a を a から取ると作れます。

a = "aa" b = "ab" c = "aaba"
true

例 3

c の 2 文字目と 3 文字目は b が 2 つ続きます。a と b の b はどちらも a の後ろにあるので、b を 2 つ続けて取るには、先に a を 2 つ取っておかないといけません。c の b より前には a が 1 つしかないので、作れません。

a = "ab" b = "ab" c = "abba"
false

面接での聞かれ方

面接では、2 つの文字列を表の縦と横に取る動的計画の、少し難しい 1 問として出されます。

  • 「2 つの文字列を順を保って混ぜると、3 つ目の文字列になりますか」
  • 前から合う方を取っていく書き方を出すと、「同じ文字が両方にあったら?」と聞かれます
  • 書き終えると「表を 1 行分に減らせますか?」と続きます

例 2 のように、両方の先頭が同じ文字のときに、どちらから取るかを決められないのがこの問題の芯です。

ヒント

まだ開いていません

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

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

アルゴリズムのチートシートの「動的計画法 (DP)」に、この型の要点を表とコードでまとめています。

動的計画法は、途中の答えを覚えておいて、同じ計算をやり直さない書き方です。漸化式で言い直せる問題が多いです。

main.py
def can_interleave(a: str, b: str, c: str) -> bool:
    """
    Goal: 何を返すか

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

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

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


# 「実行」を押すと、この行の結果が出ます
print(can_interleave("abc", "xy", "axbyc"))

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