0x01.问题
给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。)
输入示例:
[[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
解释:最大的岛屿面积为6
C++函数形式为: int maxAreaOfIsland(vector<vector<int>>& grid)
0x02.分析问题
要想得到一个小岛屿的面积,我们第一感觉肯定就是搜索,怎么搜索呢,遍历每一个结点,如果是1,就开始搜索,直到把这个结点所在的岛屿全部遍历到,然后可以得到这个岛屿的面积,具体的搜索过程,可以使用DFS,没有路了就回来,不断的回溯。
为了知道我们哪些地方是已经遍历到了的,我们的第一想法肯定就是设置一个标志数组,访问记为1,这种想法确实可以,但没有必要。
为什么呢?因为我们之前已经遍历到了的话,已经参与计数了,那么这个点就失去了它存在的意义,我们就可以假设它不存在,如何假设,有点是1,没有是0,把1变成0就可以了,这样还可以省下一个二维数组的空间,这种方法也叫 沉岛思想。
0x03.解决代码--DFS(递归)
class Solution {
public:
int DFS(int x,int y,vector<vector<int>>& grid){
if(x<0||y<0||x>=grid.size()||y>=grid[0].size()||grid[x][y]==0){
return 0;
}
int num=1;
grid[x][y]=0;
num+=DFS(x+1,y,grid);
num+=DFS(x,y+1,grid);
num+=DFS(x-1,y,grid);
num+=DFS(x,y-1,grid);
return num;
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int maxSize=0;
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[0].size();j++){
if(grid[i][j]==1){
maxSize=max(maxSize,DFS(i,j,grid));
}
}
}
return maxSize;
}
};
0x04.解决代码--DFS(栈)
思路就是访问结点访问时,我们将对围绕它四个方向进行探索,找到还未访问的结点,加入到栈中。
只要栈不为空,就从栈中取出一个元素并访问。
这样就可以达到递归同样的效果。
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int maxSize = 0;
for (int i = 0; i != grid.size(); ++i)
for (int j = 0; j != grid[0].size(); ++j) {
if (grid[i][j] == 1) {
int cur = 0;
stack<int> stacki;
stack<int> stackj;
stacki.push(i);
stackj.push(j);
while (!stacki.empty()) {
int x = stacki.top(), y = stackj.top();
stacki.pop();
stackj.pop();
if (x < 0 || y < 0 || x == grid.size() || y == grid[0].size() || grid[x][y] != 1)
continue;
++cur;
grid[x][y] = 0;
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };
for (int index = 0; index != 4; ++index) {
int next_x = x + dx[index], next_y = y + dy[index];
stacki.push(next_x);
stackj.push(next_y);
}
}
maxSize = max(maxSize, cur);
}
}
return maxSize;
}
};
0x05.解决代码--BFS(广度,队列)
思路是每次从队首取出结点,并将接下来想要遍历的土地放在队尾,就实现了广度的搜索。
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int maxSize = 0;
for (int i = 0; i != grid.size(); ++i)
for (int j = 0; j != grid[0].size(); ++j) {
if (grid[i][j] == 1) {
int cur = 0;
queue<int> queuei;
queue<int> queuej;
queuei.push(i);
queuej.push(j);
while (!queuei.empty()) {
int x = queuei.front(), y = queuej.front();
queuei.pop();
queuej.pop();
if (x < 0 || y < 0 || x == grid.size() || y == grid[0].size() || grid[x][y] != 1)
continue;
++cur;
grid[x][y] = 0;
int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };
for (int index = 0; index != 4; ++index) {
int next_x = x + dx[index], next_y = y + dy[index];
queuei.push(next_x);
queuej.push(next_y);
}
}
maxSize = max(maxSize, cur);
}
}
return maxSize;
}
};
ATFWUS --Writing By 2020--03--15