695、岛屿的最大面积
给定一个包含了一些 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。
题解
图的深度优先搜索和广度优先搜索
1、递归dfs——深度优先搜索
class Solution {
int[] di = {0,1,0,-1};
int[] dj = {1,0,-1,0};
// 递归——深度优先搜索
private int dfs(int[][] grid,int i,int j) {
if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] != 1) {
return 0;
}
int ans = 1;
grid[i][j] = 0;
for (int k = 0;k < 4;k++) {
int next_i = i + di[k];
int next_j = j + dj[k];
ans += dfs(grid,next_i,next_j);
}
return ans;
}
public int maxAreaOfIsland(int[][] grid) {
// 递归、深度优先搜索
int ans = 0;
for (int i = 0;i < grid.length;i++) {
for (int j = 0;j < grid[0].length;j++) {
if (grid[i][j] != 0) {
ans = Math.max(ans,dfs(grid,i,j));
}
}
}
return ans;
}
}
- C++ 实现
class Solution {
int dfs(vector<vector<int>>& grid, int cur_i, int cur_j) {
if (cur_i < 0 || cur_j < 0 || cur_i == grid.size() || cur_j == grid[0].size() || grid[cur_i][cur_j] != 1)
return 0;
grid[cur_i][cur_j] = 0;
int di[4] = {0, 0, 1, -1};
int dj[4] = {1, -1, 0, 0};
int ans = 1;
for (int index = 0; index != 4; ++index) {
int next_i = cur_i + di[index], next_j = cur_j + dj[index];
ans += dfs(grid, next_i, next_j);
}
return ans;
}
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)
ans = max(ans, dfs(grid, i, j));
return ans;
}
};
// 链接:https://leetcode-cn.com/problems/max-area-of-island/solution/dao-yu-de-zui-da-mian-ji-by-leetcode-solution/
2、用栈的迭代法实现深度优先搜索
- C++ 实现
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;
}
};
// 作者:LeetCode-Solution
// 链接:https://leetcode-cn.com/problems/max-area-of-island/solution/dao-yu-de-zui-da-mian-ji-by-leetcode-solution/
- java实现
class Solution{
public int maxAreaOfIsland(int[][] grid) {
Stack<Integer> stacki = new Stack<>();
Stack<Integer> stackj = new Stack<>();
int[] di = {0,0,-1,1};
int[] dj = {1,-1,0,0};
int cur = 0;
int ans = 0;
// 遍历所有位置
for (int i = 0;i < grid.length;i++) {
for (int j = 0;j < grid[0].length;j++) {
stacki.push(i);
stackj.push(j);
// 栈不为空
while (!stacki.isEmpty()) {
int curi = stacki.pop();
int curj = stackj.pop();
// 非法位置
if (curi < 0 || curj < 0 || curi >= grid.length || curj >= grid[0].length || grid[curi][curj] != 1) {
continue;
}
// 面积累加
cur++;
// 重置为非法位置
grid[curi][curj] = 0;
int nexti,nextj;
// 四个方向遍历
for (int k = 0; k < 4;k++) {
nexti = curi + di[k];
nextj = curj + dj[k];
stacki.push(nexti);
stackj.push(nextj);
}
}
// 更新最大面积
ans = Math.max(ans,cur);
// 状态重置
cur = 0;
stacki.clear();
stackj.clear();
}
}
return ans;
}
}
3、广度优先搜索
- c++
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;
queue<int> queuei;
queue<int> queuej;
queuei.push(i);
queuej.push(j);
while (!queuei.empty()) {
int cur_i = queuei.front(), cur_j = queuej.front();
queuei.pop();
queuej.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];
queuei.push(next_i);
queuej.push(next_j);
}
}
ans = max(ans, cur);
}
return ans;
}
};
// 作者:LeetCode-Solution
// 链接:https://leetcode-cn.com/problems/max-area-of-island/solution/dao-yu-de-zui-da-mian-ji-by-leetcode-solution/
- java
class Solution{
public int maxAreaOfIsland(int[][] grid) {
int ans = 0;
Queue<Integer> queuei = new LinkedList<>();
Queue<Integer> queuej = new LinkedList<>();
int[] di = {0,0,-1,1};
int[] dj = {1,-1,0,0};
int cur = 0;
for (int i = 0;i < grid.length;i++) {
for (int j = 0;j < grid[0].length;j++) {
queuei.offer(i);
queuej.offer(j);
// 队列不为空
while (!queuei.isEmpty()) {
// 获取下一个位置
int curi = queuei.poll();
int curj = queuej.poll();
// 非法位置
if (curi < 0 || curj < 0 || curi == grid.length || curj == grid[0].length || grid[curi][curj] != 1) {
continue;
}
// 计数+1
cur++;
// 置位非法位置
grid[curi][curj] = 0;
int nexti,nextj;
for (int k = 0; k < 4;k++) {
nexti = curi + di[k];
nextj = curj + dj[k];
queuei.offer(nexti);
queuej.offer(nextj);
}
}
// 更新最大岛屿的面积
ans = Math.max(ans,cur);
// 重置状态
cur = 0;
queuei.clear();
queuej.clear();
}
}
// 返回结果
return ans;
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com