バックトラックで文字の盤の上をたどって言葉が作れるか調べる

英字が升目に並んだ盤の上で、隣り合うマスをたどって言葉を作れるかを調べます。通ったマスに印を付けて進み、行き止まりなら印を外して戻る練習です。

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

問題

言葉探しのパズルの盤を、英大文字の行の並び grid で受け取ります。grid[r] は r 行目の文字列で、その c 字目が r 行 c 列のマスの字です。言葉 word を、盤の上で次の決まりでたどって作れるなら true、作れなければ false を返す関数を書いてください。

  • どのマスから始めてもかまいません
  • 次の字へは、上下左右のどれかで隣り合うマスへ進みます。斜めには進めません
  • 1 つの言葉の中で、同じマスを 2 回使うことはできません
  • 行の数と列の数はどちらも 1 以上 6 以下で、どの行も同じ長さです。word の長さは 1 以上 15 以下で、英大文字だけです

入力と出力の例

例 1

左上の C から下の O、右の D、右の E とたどると CODE になります。

grid = ["CAT", "ODE", "XRS"] word = "CODE"
true

例 2

CODE までは作れますが、最後の D は E の隣に 1 つしかなく、そのマスはもう使っています。同じマスは 2 回使えません。

grid = ["CAT", "ODE", "XRS"] word = "CODED"
false

例 3

右上の T から左の A までは進めますが、A の隣は C と D で、E がありません。ほかに T は無いので、TAE はたどれません。

grid = ["CAT", "ODE", "XRS"] word = "TAE"
false

面接での聞かれ方

面接では、短く次のように渡されることが多いです。

  • 「文字の 2 次元の盤と単語があります。隣り合うマスをたどって単語を作れるか返してください」
  • 書き終えると「同じマスを使わないように、どう印を付けましたか? 戻るときに何をしますか?」と聞かれます
  • 「単語がたくさんあったら?」と、トライ木と組み合わせる版へ広げて聞かれることがあります

斜めに進めるか、同じマスを使い回せるかを最初に確かめておくと、たどり方が決まります。

ヒント

まだ開いていません

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

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

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

再帰は、同じ形の小さい問題に分けて自分を呼ぶ書き方です。木の深さや、全部の組み合わせを数える問題で使います。

main.py
def word_search(grid: list[str], word: str) -> bool:
    """
    Goal: 何を返すか

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

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

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


# 「実行」を押すと、この行の結果が出ます
print(word_search(["CAT", "ODE", "XRS"], "CODE"))

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