Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで行列(グリッド)から最大の島の面積を求めるプログラム

問題の概要

0と1のみで構成された2値行列を考えてみましょう。ここでは「1」が陸地、「0」が水を表しており、島とは水に囲まれた隣接する1の集まりを指します。行列の外側(端)もすべて水に囲まれているものと仮定し、その中で最も大きな島の面積(セルの数)を求めるのが今回の課題です。

例えば、以下のような入力が与えられたとします。

0011111
0000000
0111100
0011000
0000011
0000010

この場合、最大の島は2〜3行目にまたがる6個の連結したセルで構成されているため、出力は6となります。

解法のアプローチ:DFS(深さ優先探索)

この問題は、DFS(Depth First Search:深さ優先探索)を用いることで効率的に解けます。基本的な考え方は、陸地のセルを見つけたらそこから上下左右へ探索を広げ、連結した1をすべて数え上げるというものです。まず、dfs()関数を定義します。引数にはmatrix(行列)、r(行インデックス)、c(列インデックス)を受け取ります。

  • totalを1増やし、訪問済みであることを示すためにmatrix[r][c]を0に設定します。
  • 上方向:r - 1 >= 0 かつ matrix[r - 1][c] が 1 の場合、dfs(matrix, r - 1, c) を呼び出します。
  • 左方向:c - 1 >= 0 かつ matrix[r][c - 1] が 1 の場合、dfs(matrix, r, c - 1) を呼び出します。
  • 下方向:r + 1 < 行数 かつ matrix[r + 1][c] が 1 の場合、dfs(matrix, r + 1, c) を呼び出します。
  • 右方向:c + 1 < 列数 かつ matrix[r][c + 1] が 1 の場合、dfs(matrix, r, c + 1) を呼び出します。

続いて、メイン処理では以下の手順を実行します。

  • r_len(行数)と c_len(列数)を取得し、max_island を 0 で初期化します。
  • すべてのセルを走査し、matrix[r][c] が 1 のセルを見つけたら、total をリセットして dfs() を呼び出します。
  • 探索終了後、max_island を max(max_island, total) で更新し、全セルの走査が完了したら max_island を返します。

それでは、理解を深めるために実際の実装を見てみましょう。

実装例

class Solution:
   def solve(self, matrix):
      self.r_len = len(matrix)
      self.c_len = len(matrix[0])
      max_island = 0
      for r in range(self.r_len):
         for c in range(self.c_len):
            if matrix[r][c] == 1:
               self.total = 0
               self.dfs(matrix, r, c)
               max_island = max(max_island, self.total)
      return max_island
   def dfs(self, matrix, r, c):
      self.total += 1
      matrix[r][c] = 0
      if r - 1 >= 0 and matrix[r - 1][c] == 1:
         self.dfs(matrix, r - 1, c)
      if c - 1 >= 0 and matrix[r][c - 1] == 1:
         self.dfs(matrix, r, c - 1)
      if r + 1 < self.r_len and matrix[r + 1][c] == 1:
         self.dfs(matrix, r + 1, c)
      if c + 1 < self.c_len and matrix[r][c + 1] == 1:
         self.dfs(matrix, r, c + 1)
ob = Solution()
matrix = [ [0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1, 0] ]
print(ob.solve(matrix))

入力

matrix = [
[0, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1, 0] ]

出力

6
  1. Pythonで行列の転置を求めるプログラム

    この記事では、与えられた問題に対する解法とアプローチについて詳しく解説します。 問題文 ある行列が与えられたとき、その転置を同じ行列に格納し、結果を表示する必要があります。 行列の転置とは、行を列に、列を行に入れ替えたものです。言い換えれば、行列Aの転置は、要素A[i][j]をA[j][i]と入れ替えることで得られます。 実装例 N = 4 def transpose(A): for i in range(N): for j in range(i+1, N): A[i][j], A[j][i] = A[j][i], A[i][j] # ドライ

  2. Pythonで配列内の最大要素を見つける方法【初心者向け解説】

    本記事では、配列の中から最大の要素を見つけるための解法とアプローチについて詳しく解説します。 問題の概要 配列が入力として与えられたとき、その中から最も大きい要素を見つけ出すことが課題となります。 アプローチ この問題は「線形探索」と呼ばれるシンプルな手法で解決できます。手順は以下の通りです。 まず、変数 max を配列の最初の要素で初期化します。 次に、2番目の要素から配列の末尾まで順番に走査していきます。 走査中の各要素について、現在の max の値と比較します。 要素が max より大きければ、max の値をその要素で更新します。 そうでなければ、そのまま次の要素へ進みます。 この処