来自面向大象编程,作者nettee。
这样,我们得到了网格 DFS 遍历的框架代码:
void dfs(int[][] grid, int r, int c) {
// 判断 base case: 如果坐标 (r, c) 超出了网格范围,直接返回
if (!inArea(grid, r, c)) {
return;
}
// 访问上、下、左、右四个相邻结点
dfs(grid, r - 1, c);
dfs(grid, r + 1, c);
dfs(grid, r, c - 1);
dfs(grid, r, c + 1);
}
// 判断坐标 (r, c) 是否在网格中
boolean inArea(int[][] grid, int r, int c) {
return 0 <= r && r < grid.length
&& 0 <= c && c < grid[0].length;
}
void dfs(int[][] grid, int r, int c) {
// base case 1:
if (!inArea(grid, r, c)) {
return;
}
// base case 2:如果这个格子不是陆地,直接返回
if (grid[r][c] != 1) {
return;
}
// 将格子标记为「已遍历过」
grid[r][c] = 2;
// 访问上、下、左、右四个相邻结点
dfs(grid, r - 1, c);
dfs(grid, r + 1, c);
dfs(grid, r, c - 1);
dfs(grid, r, c + 1);
}
// 判断坐标 (r, c) 是否在网格中
boolean inArea(int[][] grid, int r, int c) {
return 0 <= r && r < grid.length
&& 0 <= c && c < grid[0].length;
}
完整代码:
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[0].length; c++) {
if (grid[r][c] == 1) {
int a = area(grid, r, c);
res = Math.max(res, a);
}
}
}
return res;
}
int area(int[][] grid, int r, int c) {
if (!inArea(grid, r, c)) {
return 0;
}
if (grid[r][c] != 1) {
return 0;
}
grid[r][c] = 2;
return 1
+ area(grid, r - 1, c)
+ area(grid, r + 1, c)
+ area(grid, r, c - 1)
+ area(grid, r, c + 1);
}
boolean inArea(int[][] grid, int r, int c) {
return 0 <= r && r < grid.length
&& 0 <= c && c < grid[0].length;
}
见下一篇
void dfs(int[][] grid, int r, int c) {
// base case 1
if (!inArea(grid, r, c)) {
return;
}
// base case 2:如果这个格子不是陆地,直接返回
if (grid[r][c] != 1) {
return;
}
// 将格子标记为「已遍历过」
grid[r][c] = 2;
// 访问上、下、左、右四个相邻结点
dfs(grid, r - 1, c);
dfs(grid, r + 1, c);
dfs(grid, r, c - 1);
dfs(grid, r, c + 1);
}
// 判断坐标 (r, c) 是否在网格中
boolean inArea(int[][] grid, int r, int c) {
return 0 <= r && r < grid.length
&& 0 <= c && c < grid[0].length;
}
class Solution {
public int islandPerimeter (int[][] grid){
for (int r = 0;r<grid.length;r++) {
for (int c = 0;c<grid[0].length;c++) {
if (grid[r][c] == 1) {
// 题目限制只有一个岛屿,计算一个即可
return dfs(grid, r, c);
}
}
}
return 0;
}
int dfs(int[][] grid, int r, int c) {
// base case 1: 函数因为(r,c)超出网格范围返回,对应一条黄色的边
if (!inArea(grid, r, c)) {
return 1;
}
// base case 2: 函数因为「当前格子是0,海洋格子」返回,对应一条蓝色的边
if (grid[r][c] == 0) {
return 1;
}
// base case 3(退出出口): 函数因为「当前格子是已遍历的陆地格子」返回,和周长没关系
if (grid[r][c] == 2) {
return 0;
}
grid[r][c] = 2;
return dfs(grid, r - 1, c)
+ dfs(grid, r + 1, c)
+ dfs(grid, r, c - 1)
+ dfs(grid, r, c + 1);
}
// 判断坐标 (r, c) 是否在网格中
boolean inArea(int[][] grid, int r, int c) {
return 0 <= r && r < grid.length
&& 0 <= c && c < grid[0].length;
}
}