1. 程式人生 > 其它 >Leetcode第1254題:統計封閉島嶼的數目

Leetcode第1254題:統計封閉島嶼的數目

題目描述:

有一個二維矩陣 grid,每個位置要麼是陸地(記號為0 )要麼是水域(記號為1 )。

我們從一塊陸地出發,每次可以往上下左右4 個方向相鄰區域走,能走到的所有陸地區域,我們將其稱為一座「島嶼」。

如果一座島嶼完全由水域包圍,即陸地邊緣上下左右所有相鄰區域都是水域,那麼我們將其稱為 「封閉島嶼」。

請返回封閉島嶼的數目。

示例 1:

輸入:grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]
輸出:2
解釋:
灰色區域的島嶼是封閉島嶼,因為這座島嶼完全被水域包圍(即被 1 區域包圍)。


示例 2:

輸入:grid = [[0,0,1,0,0],[0,1,0,1,0],[0,1,1,1,0]]
輸出:1


示例 3:

輸入:grid = [[1,1,1,1,1,1,1],[1,0,0,0,0,0,1], [1,0,1,1,1,0,1], [1,0,1,0,1,0,1], [1,0,1,1,1,0,1], [1,0,0,0,0,0,1], [1,1,1,1,1,1,1]]
輸出:2

程式設計思想:泛洪演算法

實現思路:題目明確0表示陸地,1表示水域,要求找到網格內所有的封閉島嶼數目,通過分析可以發現邊界上(i = 0, i = lineLength - 1, j = 0, j = columnLength - 1)與值為0相連的陸地(0標識)

     肯定不會構成封閉島嶼,那麼我們可以利用泛紅演算法將邊界上與值為0的陸地(0標識)全部置為水域(1標識),然後再在矩陣的非邊界內尋找值等於0的陸地,當在矩陣內部找到一個0時,

     則封閉島嶼count增加1,並將陸地0置為水域1,且將與之相連的島嶼置為水域1,遍歷完count即為封閉島嶼的數量。

程式碼實現:

public class 統計封閉島嶼的數目 {

public static void main(String[] args) {
int[][] grid = {
{1,1,1,1,1,1,1,0},
{1,0,0,0,0,1,1,0},
{1,0,1,0,1,1,1,0},
{1,0,0,0,0,1,0,1},
{1,1,1,1,1,1,1,0}};
System.out.println(closedIsland(grid));
}

public static int closedIsland(int[][] grid) {
int count = 0;
int lineLength = grid.length;
int columnLength = grid[0].length;

// 利用泛洪演算法先將 i = 0, i = lineLength - 1, j = 0, j = columnLength - 1中與0相連的所有0都變成1,這樣就可以保證內部為0起始的陸地肯定是封閉島嶼,避免內部以0起始的陸地與邊界為0相連的陸地相連,這種情況不是封閉的島嶼。
for (int i = 0; i < lineLength; ++i) {
for (int j = 0; j < columnLength; ++j) {
if (isBoundary(i, j, lineLength, columnLength) && grid[i][j] == 0) {
floodFill(grid, i, j, lineLength, columnLength);
}
}
}

// 統計陣列非邊界內的非零值,並利用泛洪演算法將與0相連的0全部置為1,則統計0開始的個數即為封閉島嶼。
for (int i = 0; i < lineLength; ++i) {
for (int j = 0; j < columnLength; ++j) {
if (grid[i][j] == 0) {
count++;
floodFill(grid, i, j, lineLength, columnLength);
}
}
}

return count;
}

public static boolean isBoundary(int i, int j, int lineLength, int columnLength) {
return i == 0 || i == lineLength - 1 || j == 0 || j == columnLength - 1;
}

public static void floodFill(int[][] grid, int i, int j, int lineLength, int columnLength) {
if (i < 0 || i >= lineLength || j < 0 || j >= columnLength || grid[i][j] != 0) {
return;
}
grid[i][j] = 1;
floodFill(grid, i - 1, j, lineLength, columnLength);
floodFill(grid, i + 1, j, lineLength, columnLength);
floodFill(grid, i, j - 1, lineLength, columnLength);
floodFill(grid, i, j + 1, lineLength, columnLength);
}
}