作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/max-area-of-island/description/

题目描述

Given a non-empty 2D array grid of 0’s and 1’s, an island is a group of 1’s (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.

Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.)

Example 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]]
Given the above grid, return 6. Note the answer is not 11, because the island must be connected 4-directionally.

Example 2:

[[0,0,0,0,0,0,0,0]]
Given the above grid, return 0.

Note: The length of each dimension in the given grid does not exceed 50.

题目大意

4-联通的一个区域是一个岛,现在要统计面积最大的岛的面积。

解题方法

方法一:DFS

DFS是深度优先遍历,在不能再走的时候,要回撤再搜索。这里可能就会出现一个问题,回撤之后再搜索的时候怎么能判定哪些位置已经搜索过了,避免重复搜索问题呢?一般有两个方法:(1)使用一个visited数组保存已经走过的位置;(2)把已经走过的位置设置为不可走的状态。

下面的方法使用把已经走过的路给设成0,即不能再走。对原始的地图中所有的点都遍历一遍,找出每个点所从属的小岛的最大面积。再用一个全局的变量,记录所有小岛的最大面积。

为了便于理解,我举个例子,如果有下面的地图:

1,1
1,1

使用DFS的遍历位置的路径是这样的(蓝色),每次把遍历到的位置设置为0,下次就不会继续搜索这个已经搜索过位置(黄色)了:

python代码如下:

class Solution(object):
def maxAreaOfIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
row, col = len(grid), len(grid[0])
answer = 0
def dfs(i, j):
if 0 <= i <= row - 1 and 0 <= j <= col - 1 and grid[i][j]:
grid[i][j] = 0 # 重要,防止再次搜索
return 1 + dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1)
return 0
return max(dfs(i, j) for i in xrange(row) for j in xrange(col))

二刷,直接按照模板来写的。

class Solution(object):
def maxAreaOfIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
self.res = 0
self.island = 0
M, N = len(grid), len(grid[0])
for i in range(M):
for j in range(N):
if grid[i][j]:
self.dfs(grid, i, j)
self.res = max(self.res, self.island)
self.island = 0
return self.res def dfs(self, grid, i, j): # ensure grid[i][j] == 1
M, N = len(grid), len(grid[0])
grid[i][j] = 0
self.island += 1
dirs = [(0, 1), (0, -1), (-1, 0), (1, 0)]
for d in dirs:
x, y = i + d[0], j + d[1]
if 0 <= x < M and 0 <= y < N and grid[x][y]:
self.dfs(grid, x, y)

C++代码如下:

class Solution {
public:
vector<vector<int>> dirs{{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
int maxAreaOfIsland(vector<vector<int>>& grid) {
const int M = grid.size(), N = grid[0].size();
int res = 0, island = 0;
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
if (grid[i][j]) {
dfs(grid, i, j, island);
res = max(res, island);
island = 0;
}
}
}
return res;
}
void dfs(vector<vector<int>>& grid, int i, int j, int& island) {
const int M = grid.size(), N = grid[0].size();
grid[i][j] = 0; // 重要
island ++;
for (auto d : dirs) {
int x = i + d[0], y = j + d[1];
if (x >= 0 && x < M && y >= 0 && y < N && grid[x][y])
dfs(grid, x, y, island);
}
}
};

方法二:BFS

BFS方法也是显而易见的,只要找出一个1的节点之后,然后把所有的4联通全部都进入队列,然后搜索就好了。

这个方法需要注意的是,把一个位置放入队列的同时,应该理解把该位置置0,否则有可能被重复的放入队列。

继续举上面的个例子,如果有下面的地图:

1,1
1,1

BFS中放入队列中的顺序是这样的(蓝色),每次把遍历到的位置设置为0,下次就不会继续搜索这个已经搜索过位置(黄色)了::

因此,把每个位置放入队列之后,立马把这个位置设置为0,就可以防止下次被别的节点放进队列中了。

C++代码如下:

class Solution {
public:
vector<vector<int>> ds{{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
int maxAreaOfIsland(vector<vector<int>>& grid) {
const int M = grid.size(), N = grid[0].size();
queue<pair<int, int>> q;
int res = 0;
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
if (grid[i][j]) {
int island = 0;
q.push({i, j});
while (!q.empty()) {
auto p = q.front(); q.pop();
grid[p.first][p.second] = 0;
island ++;
for (auto d : ds) {
int x = p.first + d[0];
int y = p.second + d[1];
if (x >= 0 && x < M && y >= 0 && y < N && grid[x][y]) {
grid[x][y] = 0;
q.push({x, y});
}
}
}
res = max(res, island);
}
}
}
return res;
}
};

日期

2018 年 1 月 27 日
2018 年 12 月 10 日 —— 又是周一!
2020 年 3 月 15 日 —— 今天给这个博客新加了两个图便于理解

【LeetCode】695. Max Area of Island 解题报告(Python & C++)的更多相关文章

  1. LeetCode 695. Max Area of Island (岛的最大区域)

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  2. [Leetcode]695. Max Area of Island

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  3. leetcode 695 Max Area of Island 岛的最大面积

    这个题使用深度优先搜索就可以直接遍历 DFS递归方法: class Solution { public: vector<vector<,},{,-},{,},{,}}; int maxAr ...

  4. leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions

    两种方式处理已经访问过的节点:一种是用visited存储已经访问过的1:另一种是通过改变原始数值的值,比如将1改成-1,这样小于等于0的都会停止. Number of Islands 用了第一种方式, ...

  5. [leetcode]python 695. Max Area of Island

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  6. 【leetcode】Max Area of Island

    国庆中秋长假过完,又要开始上班啦.先刷个题目找找工作状态. Given a non-empty 2D array grid of 0's and 1's, an island is a group o ...

  7. 200. Number of Islands + 695. Max Area of Island

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  8. 【easy】695. Max Area of Island

    题目: Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) ...

  9. 695. Max Area of Island最大岛屿面积

    [抄题]: 求最多的联通的1的数量 Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (repre ...

随机推荐

  1. 『学了就忘』Linux文件系统管理 — 64、磁盘配额的配置步骤

    目录 1.手工建立一个5GB的分区 2.建立需要做限制的三个用户 3.在分区上开启磁盘配额功能 4.建立磁盘配额的配置文件 5.开始设置用户和组的配额限制 6.启动和关闭配额 7.磁盘配额的查询 8. ...

  2. idea 启动debug的时候throw new ClassNotFoundException(name)

    idea 启动debug的时候throw new ClassNotFoundException(name) 启动debug就跳转到此界面 解决办法 这个方法只是忽略了抛异常的点,并没有真正解决问题.后 ...

  3. 日常Java测试第二段 2021/11/12

    第二阶段 package word_show; import java.io.*;import java.util.*;import java.util.Map.Entry; public class ...

  4. 关于java中的安全管理器

    最近再查看java的源码的时候看见了这一类代码 final SecurityManager sm = System.getSecurityManager(); 想要了解这个是为了做什么,查看资料之后发 ...

  5. doy05循环语法学习笔记

    doy05循环语法学习笔记 一.while循环语法: 1.基本用法示例 x = 1 while x <= 5: print(x) x += 1 2.死循环:永远不结束的循环 如:while Tr ...

  6. Android WifiP2p实现

    Android WifiP2p实现 Wifi Direct功能早在Android 4.0就以经加入Android系统了,但是一直没有很好的被支持,主要原因是比较耗电而且连接并不是很稳定.但是也有很大的 ...

  7. JAVA中的六种日期类型使用

    基本的6种日期类 /** * 六种时间类型的类 * 数据库格式的时间三种格式 */ java.util.Date date = new java.util.Date();//年与日时分秒 //数据库的 ...

  8. GO 通过进程号输出运行运行信息

    操作系统应用可以使用PID来查找关于进程本身的信息.当进程失败时获取到的PID就非常有价值,这样就可以使用PID跟踪整个系统中的系统日志,如/var/log/messages./var/log/sys ...

  9. Linux学习 - 文件包处理命令

    一.搜索文件find find  [搜索范围]  [匹配条件] (1) -name(名字查找) <1>  find  /etc  -name  init 查找/etc下以 "in ...

  10. django搭建示例-ubantu环境

    python3安装--------------------------------------------------------------------------- 最新的django依赖pyth ...