盤の端からたどって囲まれた空き地だけを埋める

グラフ問題 113

土と水のマスが並んだ盤で、盤の端につながっていない水のまとまりを土で埋めた盤を返します。囲まれた所を探すのではなく、端から届く水に印を付けて、残りを埋める練習です。

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

問題

畑の区画を表す盤を、行の文字列の並び board で受け取ります。各マスは "X" (土) か "O" (水) です。上下左右で隣り合う水どうしは、同じ水たまりに属します。

畑の外は川で、盤の端の水は川へ流れ出せます。水たまりのうち、どのマスも盤の端に無い (盤の端の水と上下左右でつながっていない) 物は流れ出せないので、土で埋めます。埋めたあとの盤を、同じ形の行の文字列の並びで返す関数を書いてください。

  • 盤の端につながっている水たまりは、そのまま残します
  • 斜めにしか隣り合っていない水どうしは、つながっていないものとします
  • 行の数と列の数は、どちらも 1 以上 50 以下です。どの行も同じ長さです

入力と出力の例

例 1

まん中の 3 マスの水たまりは、端に届かないので埋めます。上の行の右から 2 つ目の水は盤の端にあるので残ります。

board = ["XXOX", "XXXX", "XOOX", "XOXX", "XXXX"]
["XXOX", "XXXX", "XXXX", "XXXX", "XXXX"]

例 2

右下の水たまりは、右の端の水とつながっているので残ります。左上の 1 マスだけが埋まります。

board = ["XXXXX", "XOXXX", "XXXOO", "XXXOX"]
["XXXXX", "XXXXX", "XXXOO", "XXXOX"]

例 3

1 行だけの盤では、どのマスも端にあるので、何も埋まりません。

board = ["OXO"]
["OXO"]

面接での聞かれ方

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

  • 「X と O の盤で、X に囲まれた O の領域を全部 X に書き換えてください」
  • 囲まれた領域を 1 つずつ調べる書き方を出すと、「逆から考えられませんか? 囲まれていない方が見つけやすくないですか?」と聞かれます
  • LeetCode では盤をその場で書き換えますが、ここでは書き換えた盤を返す形にしています

「囲まれている」の決め方 (端にあるマスとつながっていない) を最初に確かめておくと、端から探す考えにすぐ進めます。

ヒント

まだ開いていません

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

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

アルゴリズムのチートシートの「グラフ探索と幅優先探索」に、この型の要点を表とコードでまとめています。

グラフ探索は、つながりを近い順か奥からたどります。迷路、最短の手数、講座を受ける順のような問題が同じ形です。

main.py
def surround_regions(board: list[str]) -> list[str]:
    """
    Goal: 何を返すか

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

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

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


# 「実行」を押すと、この行の結果が出ます
print(surround_regions(["XXOX", "XXXX", "XOOX", "XOXX", "XXXX"]))

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