文章目录
Problem: LCR 105. 岛屿的最大面积
思路
本题中说的是一个网格的岛屿,获取其中的岛屿的最大面积,是典型的图论的问题,可以采用广度优先搜索算法和深度优先算法,本文采用广度优先搜索算法
解题方法
① 定义已经访问过的岛屿的二维布尔数组
② 两层循环遍历网格,即第一层(最外层)循环是网格的行,第二层(最内层)循环是网格的列
③ 遍历到每个网格节点时,判断该节点时岛屿(其值是1),同时不是已经访问过的岛屿,则获取其岛屿的面积,并与最大的岛屿面积比较
④ 获取岛屿的面积的子函数 getArea(), 入参只要是 网格,是否已经访问过的二维数组,当前节点的横坐标,当前节点的纵坐标;返回值是整型的岛屿的面积
⑤ 获取岛屿面积的子函数中,定一个 岛屿节点Queue, Java语言中,就使用 LinkedList
实现就行,当前节点放入该队列,当前节点已访问,定义当前岛屿面积 area;
⑥ while循环岛屿节点队列,remove出当前岛屿节点,同时面积area增加1;for循环当前岛屿的前后左右四个节点,还是判断这四个节点的,纵横坐标是否在网格中,同时是否是岛屿,是否还没访问过,如果是的话,就放入到 岛屿节点队列中,这个节点被访问过
复杂度
-
时间复杂度: 两层循环,时间复杂度: O(n2)O(n^2)
O(n2) -
空间复杂度:空间复杂度: O(n)
Code
4.1)Java实现
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int maxArea = 0;
int row = grid.length;
int col = grid[0].length;
// 岛屿是否访问过的二维布尔数组
boolean[][] visited = new boolean[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
// 节点是岛屿且没被访问过
if (grid[i][j] == 1 && !visited[i][j]) {
int area = getArea(grid, visited, i, j);
maxArea = Math.max(area, maxArea);
}
}
}
return maxArea;
}
private int getArea(int[][] grid, boolean[][] visited, int i, int j) {
// 岛屿节点队列
Queue<int[]> queue = new LinkedList<>();
int area = 0;
queue.add(new int[]{
i, j});
visited[i][j] = true;
// 岛屿的前后左右的四个方向
int[][] dirs = {
{
-1, 0}, {
1, 0}, {
0, -1}, {
0, 1}};
// 广度优先搜索
while (!queue.isEmpty()) {
// 当前节点
int[] pos = queue.remove();
area++;
for (int[] dir : dirs) {
int r = pos[0] + dir[0];
int c = pos[1] + dir[1];
if (r >= 0 && r < grid.length
&& c >= 0 && c < grid[0].length
&& grid[r][c] == 1 && !visited[r][c]) {
queue.add(new int[]{
r, c});
visited[r][c] = true;
}
}
}
return area;
}
}
4.2)Python实现
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
maxArea = 0
# 网格的行列
row,col = len(grid), len(grid[0])
# 岛屿是否遍历过
visited = [[False for _ in range(col)] for _ in range(row)]
for i in range(row):
for j in range(col):
# 是没有访问过的岛屿
if grid[i][j] == 1 and not visited[i][j]:
area = self.getNowArea(grid, visited, i, j)
# 获取较大值
maxArea = max(maxArea, area)
return maxArea
def getNowArea(self, grid: List[List[int]], visited: List[List[bool]], i: int, j: int) -> int:
area = 0
# from Collections import dequeue
queue = deque([(i, j)])
# 当前节点被访问过
visited[i][j] = True
# 当前节点的前后左右4个方向
dirs = [(-1,0), (1,0), (0,-1), (0,1)]
# 广度优先算法
while queue:
pos = queue.popleft()
area += 1
for dirItem in dirs:
row,col = pos[0] + dirItem[0], pos[1] + dirItem[1]
# 在网格的边界访问里,同时是未被访问过的岛屿
if 0 <= col < len(grid[0]) and 0 <= row < len(grid) and grid[row][col] == 1 and not visited[row][col]:
queue.append((row, col))
visited[row][col] = True
return area
- python中的函数第1个参数要是 self
- 返回值的表现可以是 def yourFunction(self) -> int :
- Python中访问同一个类中的其他方法,可以是 self.otherfun()
- 不能自定义,但不初始化 python的变量,比如 本题中的是否被访问过的 二维布尔列表
visited = [[False for _ in range(col)] for _ in range(row)]
- python中没有 三元判断符,使用 max()函数即可
6) if判断语句不用使用小括号,“且”是and
, "或"是or
, 非是not
- python中的队列是 deque()
from Collections import deque
左侧出队列是queue.popleft()
返回值是 弹出来的元素
8)布尔类型: bool
真:True
假: False