Pythonで行列(グリッド)から最大の島の面積を求めるプログラム
問題の概要
0と1のみで構成された2値行列を考えてみましょう。ここでは「1」が陸地、「0」が水を表しており、島とは水に囲まれた隣接する1の集まりを指します。行列の外側(端)もすべて水に囲まれているものと仮定し、その中で最も大きな島の面積(セルの数)を求めるのが今回の課題です。
例えば、以下のような入力が与えられたとします。
| 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 |
この場合、最大の島は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
-
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] # ドライ
-
Pythonで配列内の最大要素を見つける方法【初心者向け解説】
本記事では、配列の中から最大の要素を見つけるための解法とアプローチについて詳しく解説します。 問題の概要 配列が入力として与えられたとき、その中から最も大きい要素を見つけ出すことが課題となります。 アプローチ この問題は「線形探索」と呼ばれるシンプルな手法で解決できます。手順は以下の通りです。 まず、変数 max を配列の最初の要素で初期化します。 次に、2番目の要素から配列の末尾まで順番に走査していきます。 走査中の各要素について、現在の max の値と比較します。 要素が max より大きければ、max の値をその要素で更新します。 そうでなければ、そのまま次の要素へ進みます。 この処