Medium
思想
- 遍历所有点,判断点是否为陆地
- 如果是陆地, recursion去判断周围, 上下左右是否为陆地, 目的是寻找边界
过程
- 二维数组, 长/宽度:grid[0].length, 高:grid.length
- for循环遍历所有的点
- 如果是水就放过, 如果为陆地就dfs
- 一个dfs结束证明完成了一个岛屿,count++
dfs过程
- base case : 出界,或, 已经为水
- recursion过程中每路过一个点(dfs中当然这个点为陆地点), 就将这个点变为水,以表明已经计算过这个点
- 如何让dfs中的点走起来? 建立坐标系,for循环实现
int[] dx = {0, 1, 0, -1};
int[] dy = {1, 0, -1, 0};
dfs(char[] g, int i, int j){
for(int k = 0; k < 4; k++){
dfs(g, i + dx[k], j + dy[k]);
}
}
复杂度
- 时间: O(mn) 主函数里的双层loop
- 空间: 最坏为O(mn), 当dfs遍历了所有的点,意味着二维数组开始全部为陆地
代码
class Solution {
int[] dx = {0, 1, 0 ,-1};
int[] dy = {1, 0, -1, 0};
public int numIslands(char[][] grid) {
if(grid == null || grid.length == 0 || grid[0].length == 0)
return 0;
int length = grid.length;
int height = grid[0].length;
int res = 0;
for(int i = 0; i < length; i++){
for(int j = 0; j < height; j++){
if(grid[i][j] == '1'){
dfs(grid, i, j);
res++;
}
}
}
return res;
}
private void dfs(char[][] grid, int i, int j){
if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') return;
grid[i][j] = '0';
for(int k = 0; k < 4; k++){
dfs(grid, i + dx[k], j + dy[k]);
}
}
}