本文为博主原创文章,未经允许不得转载。如有问题,欢迎指正!
题目描述:
给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻
的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:
[
[‘1’,‘1’,‘1’,‘1’,‘0’],
[‘1’,‘1’,‘0’,‘1’,‘0’],
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘0’,‘0’,‘0’,‘0’,‘0’]
]
输出: 1
示例 2:
输入:
[
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘1’,‘1’,‘0’,‘0’,‘0’],
[‘0’,‘0’,‘1’,‘0’,‘0’],
[‘0’,‘0’,‘0’,‘1’,‘1’]
]
输出: 3
解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。
来源:力扣(LeetCode)
题目链接:https://leetcode-cn.com/problems/number-of-islands
思路:
- 对点(i,j)进行dfs,如果当前点(i,j)是‘1’(陆地),就对其周围的点进行dfs,最终让dfs函数返回true,表示搜到了一块陆地。在dfs的过程中将已经访问过的‘1’(陆地)置为‘0’(水),防止重复访问。
- 当位置(x,y)越界、或(x,y)是‘0’(水)的时候就停止dfs并返回false,表示当前位置不是陆地。
- 尝试对网格上的每一个点进行dfs,如果dfs返回true,就增加岛屿数ans。
AC代码:
/ /AC代码(c++):
class Solution {
public:
bool dfs(int x,int y,vector<vector<char>>& grid,int M,int N){
if(x>=M||x<0||y>=N||y<0) return false;
if(grid[x][y]=='0') return false;
grid[x][y]='0'; / /将'1'(陆地)置为'0'(水),防止重复访问
int dx[4]={
1,-1,0,0},dy[4]={
0,0,1,-1};/ /方向数组
for(int k=0;k<=3;k++){
dfs(x+dx[k],y+dy[k],grid,M,N);/ /对周围的点进行dfs
}
return true; / /返回true表示搜到一块陆地
}
int numIslands(vector<vector<char>>& grid) {
if(grid.empty()) return 0; / /网格为空就返回0
int M=grid.size(),N=grid[0].size();/ /获取网格的行M和和列N
int ans=0;
for(int i=0;i<M;i++){
/ /对网格进行dfs
for(int j=0;j<N;j++){
if(dfs(i,j,grid,M,N)) / /如果搜到陆地,ans++
ans++;
}
}
return ans;
}
};
小结:
- 一个递归函数的最终返回值对应最顶层的调用。例如入门时学的“递归求阶乘”,f(5)在递归的过程中每一步都有返回值,但最终返回的是5!而此处的dfs在递归的过程中同样每一步都有返回值,但最终返回的是当前点(i,j)是(true)否(false)为陆地。
- 第一次没加if(grid.empty()) return 0; 报错:Line 924: Char 9: runtime error: reference binding to null pointer of type 'std::vector<char, std::allocator<…。将报错信息百度就找到了原因QWQ。