題目:200. 島嶼數量
public class NumIslands_200 {
public static void main(String[] args) {
char[][] grid = {
{ '1', '1', '1', '1', '0' },
{ '1', '1', '0', '1', '0' },
{ '1', '1', '0', '0', '0' },
{ '0', '0', '0', '0', '0' }};
System.out.println(numIslands(grid));
}
/** 網格 */
private static char[][] grid;
/** 網格行數 */
private static int row;
/** 網格列數 */
private static int col;
/** 標記數組:標記格子是否訪問過 */
private static boolean[][] marked;
/** 方向數組:上下左右 */
private static final int[][] directions = {
{ -1, 0 },
{ 0, 1 },
{ 1, 0 },
{ 0, -1 }};
/** 隊列 */
private static LinkedList<Integer> queue = new LinkedList<>();
/**
* 獲取島嶼的數量
* @param grid 網格
* @return 網格中島嶼的數量
*/
public static int numIslands(char[][] grid) {
row = grid.length;
// 如果數組爲空,直接返回
if (row == 0) {
return 0;
}
col = grid[0].length;
// 使用成員變量,避免來回傳遞數組
NumIslands_200.grid = grid;
// 初始化訪問標記數組
marked = new boolean[row][col];
// 島嶼數量
int res = 0;
// 遍歷網格數組
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
// 未被訪問,並且是陸地的時候
if (!marked[i][j] && grid[i][j] == '1') {
// 廣度優先搜索
// bfs(i, j);
// 深度優先搜索
dfs(i, j);
res++;
}
}
}
return res;
}
/**
* 廣度優先搜索
* @param i 網格的行座標
* @param j 網格的列座標
*/
public static void bfs(int i, int j) {
// 先置爲訪問
marked[i][j] = true;
// 座標轉換成值入隊列
queue.addLast(i * col + j);
while (!queue.isEmpty()) {
// 頭節點出隊
int head = queue.removeFirst();
// 還原座標
int headX = head / col;
int headY = head % col;
// 探索四個方向是否是陸地
for (int k = 0; k < 4; k++) {
int newX = headX + directions[k][0];
int newY = headY + directions[k][1];
// 未越界,未被訪問,並且是陸地的時候
if (isInArea(newX, newY) && !marked[newX][newY] && grid[newX][newY] == '1') {
// 節點入隊列
queue.addLast(newX * col + newY);
// 當前節點置爲訪問
marked[newX][newY] = true;
}
}
}
}
/**
* 深度優先搜索
* @param i 網格的行座標
* @param j 網格的列座標
*/
private static void dfs(int i, int j) {
marked[i][j] = true;
// 探索四個方向是否是陸地
for (int k = 0; k < 4; k++) {
int newX = i + directions[k][0];
int newY = j + directions[k][1];
// 未越界,未被訪問,並且是陸地的時候
if (isInArea(newX, newY) && !marked[newX][newY] && grid[newX][newY] == '1') {
// 遞歸遍歷
dfs(newX, newY);
}
}
}
/**
* 判斷座標 (x, y) 是否在網格內
* @param x 行座標
* @param y 列座標
* @return true 在網格內
*/
public static boolean isInArea(int x, int y) {
return 0 <= x && x < row && 0 <= y && y < col;
}
}