题目描述(题目链接)
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1
示例 2:
输入:grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
求解思路
回溯法的思想:遍历数组,遇到一个为‘0’的,就开始深度优先搜索,搜索其上下左右四个方向上与其属于同一岛屿的字符,并将其置为‘0’。可以理解为:每次从第一个‘1’开始的深度优先搜索都消灭了一个岛屿,执行多少次深度优先搜索就是有多少个岛屿。
ps:刚开始试了动态规划(但由于需要四个方向的,行不通)、分治(分治完合并的时候太复杂,也行不通)。没想到最后回溯法dfs竟然效率还挺高。
java代码
执行用时:1 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:41 MB, 在所有 Java 提交中击败了33.96%的用户
class Solution {
int leny;
int lenx;
public int numIslands(char[][] grid) {
leny = grid.length;
lenx = grid[0].length;
int num = 0; //用来记录岛屿的数量
for(int i=0;i<leny;i++){
for(int j=0;j<lenx;j++){
if(grid[i][j]=='1'){ //当出现为1的点时,将其值置为0,并对其进行深度优先搜索
grid[i][j] = '0';
num++; //岛屿数量+1
dfs(grid,i,j);
}
}
}
return num;
}
void dfs(char[][] grid,int y,int x){ //深度优先搜索
if(y-1>=0&&grid[y-1][x]=='1'){ //上
grid[y-1][x] = '0';
dfs(grid,y-1,x);
}
if(x-1>=0&&grid[y][x-1]=='1'){ //左
grid[y][x-1] = '0';
dfs(grid,y,x-1);
}
if(y+1<leny&&grid[y+1][x]=='1'){ //下
grid[y+1][x] = '0';
dfs(grid,y+1,x);
}
if(x+1<lenx&&grid[y][x+1]=='1'){ //右
grid[y][x+1] = '0';
dfs(grid,y,x+1);
}
}
}