给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。)
实例1:
[[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]
对于上面这个给定矩阵应返回 6。注意答案不应该是11,因为岛屿只能包含水平或垂直的四个方向的‘1’。
实例2:
[[0,0,0,0,0,0,0,0]]
对于上面这个给定的矩阵, 返回 0。
注意: 给定的矩阵grid 的长度和宽度都不超过 50。
求网格中最大的连通区域的面积,最直观的思路就是使用BFS或者DFS搜索出每一个连通区域的面积。
算法如下:遍历整个地图,遇到 == 1的结点就开始深搜或者广搜,为了避免结点的重复搜索,将搜索过的位置的值置为0。
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid)
{
int maxArea = 0;
for (int i = 0; i < grid.size(); i++){
for (int j = 0; j < grid[0].size(); j++){
if (grid[i][j] == 1){
maxArea = max(maxArea, dfs(grid, i, j));
}
}
}
return maxArea;
}
int dfs(vector<vector<int>>& grid, int x, int y)
{
if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == 0) return 0;
int addX[4] = {0, 0, 1, -1};
int addY[4] = {1, -1, 0, 0};
int area = 0;
grid[x][y] = 0;
for (int i = 0; i < 4; i++){
area += dfs(grid, x + addX[i], y + addY[i]);
}
return 1 + area;
}
//BFS只需将函数部分替换即可
int bfs(vector<vector<int>>& grid, int x, int y)
{
queue<pair<int, int> > nodes;
nodes.push(make_pair(x, y));
int addX[4] = {0, 0, 1, -1};
int addY[4] = {1, -1, 0, 0};
int area = 1;
grid[x][y] = 0;
while (!nodes.empty()){
pair<int, int> temp = nodes.front();
nodes.pop();
x = temp.first, y = temp.second;
for (int i = 0; i < 4; i++){
int width = grid.size(), height = grid[0].size();
int newX = x + addX[i], newY = y + addY[i];
if (newX < 0 || newX >= width || newY < 0 || newY >= height || grid[newX][newY] == 0){
continue;
}
grid[newX][newY] = 0;
nodes.push(make_pair(newX, newY));
area++;
}
}
return area;
}
};
最后是LeetCode题解上看来的栈解法,对于DFS,也可以采用栈来实现,这样可以省去递归算法中函数调用的时间:题解
把想要访问的结点放到栈里,当取出时就访问它。如果栈不为空则说明我们仍然有想要访问的结点。(本质上没啥区别)
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int ans = 0;
for (int i = 0; i != grid.size(); ++i)
for (int j = 0; j != grid[0].size(); ++j) {
int cur = 0;
stack<int> stacki;
stack<int> stackj;
stacki.push(i);
stackj.push(j);
while (!stacki.empty()) {
int cur_i = stacki.top(), cur_j = stackj.top();
stacki.pop();
stackj.pop();
if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1)
continue;
++cur;
grid[cur_i][cur_j] = 0;
int di[4] = {0, 0, 1, -1};
int dj[4] = {1, -1, 0, 0};
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index];
stacki.push(next_i);
stackj.push(next_j);
}
}
ans = max(ans, cur);
}
return ans;
}
};