深さ優先探索 (DFS) でグリッドのいちばん大きい島の広さを求める

グラフ問題 112

陸と海のマスが並んだ地図から、上下左右につながった陸のまとまり (島) のうち、いちばん広い島のマスの数を返します。島を見つけたら塗りつぶしながら数える練習です。

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

問題

海の上から撮った地図を、2 次元の並び grid で受け取ります。各マスは数の 1 (陸) か 0 (海) です。上下左右のどれかで隣り合う陸どうしは、同じ島に属します。島の広さは、その島の陸のマスの数です。いちばん広い島の広さを返す関数を書いてください。陸が 1 つも無ければ 0 を返します。

  • 斜めに隣り合うだけの陸は、つながっていないものとします
  • 地図の外側は、すべて海だと考えます
  • 行の数と列の数は、どちらも 1 以上 50 以下です。どの行も同じ長さです
  • 関数の中で grid を書き換えてかまいません

入力と出力の例

例 1

左上の島は 4 マス、右下の島は 3 マス、右上の島は 1 マスです。いちばん広いのは 4 です。

grid = [[1, 1, 0, 0, 1], [0, 1, 1, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1]]
4

例 2

陸がありません。

grid = [[0, 0], [0, 0]]
0

例 3

斜めにしか隣り合っていない陸は別々の島です。どの島も 1 マスです。

grid = [[1, 0, 1], [0, 1, 0]]
1

面接での聞かれ方

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

  • 「0 と 1 のグリッドで、1 がつながった島のうち、いちばん大きい島の面積を返してください」
  • 島の数を数える問題のあとに、続けて出されることが多い問題です。「島の数のコードから、どこを変えましたか?」と聞かれます
  • 書き終えると「再帰で書くと、地図が大きいとき何が起きますか?」と、呼び出しの深さを聞かれることがあります

斜めのつながりを数えるかと、入力を書き換えてよいかを最初に確かめておくと、塗りつぶす書き方を選べます。

ヒント

まだ開いていません

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

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

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

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

main.py
def max_island_area(grid: list[list[int]]) -> int:
    """
    Goal: 何を返すか

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

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

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


# 「実行」を押すと、この行の結果が出ます
print(max_island_area([[1, 1, 0, 0, 1], [0, 1, 1, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1]]))

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