Open azl397985856 opened 3 years ago
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
for i, l in enumerate(grid):
for j, n in enumerate(l):
ans = max(self.dfs(grid, i, j), ans)
return ans
def dfs(self, grid, cur_i, cur_j) -> int:
if cur_i < 0 or cur_j < 0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] != 1:
return 0
grid[cur_i][cur_j] = 0
ans = 1
for di, dj in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
next_i, next_j = cur_i + di, cur_j + dj
ans += self.dfs(grid, next_i, next_j)
return ans
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m_s :int = 0
m = len(grid)
n = len(grid[0])
t :int = 0
def infection(i,j):
nonlocal t
nonlocal grid
nonlocal m_s
if i>-1 and i< m and j>-1 and j<n and grid[i][j] == 1:
t+=1
#改变值
grid[i][j] = 0
infection(i-1,j)
infection(i+1,j)
infection(i,j-1)
infection(i,j+1)
if m_s < t:
m_s = t
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
t = 0
infection(i,j)
return m_s
class Solution(object):
def maxAreaOfIsland(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
rows, cols = len(grid), len(grid[0])
res = 0
for i in range(rows):
for j in range(cols):
res = max(res, self.bfs(grid, rows, cols, i, j))
return res
def bfs(self, grid, rows, cols, i, j):
if i<0 or i>=rows or j<0 or j>=cols or grid[i][j]==0:
return 0
grid[i][j] = 0
res = 1
for d in [[-1,0],[0,-1],[1,0],[0,1]]:
res += self.bfs(grid, rows, cols, i+d[0], j+d[1])
return res
时间复杂度:O(mn) 空间复杂度:O(mn)
dfs 搜索遍历为 1 的点并更新 visited[x][y] 状态和 max 最大岛屿面积;
const int dx[] = {0, 0, -1, 1};
const int dy[] = {-1, 1, 0, 0};
int maxAreaOfIsland(vector<vector<int>> grid) {
int maxRes = 0;
int counter = 0;
queue<int> q;
int m = grid.size();
int n = grid[0].size();
int totalSize = m * n;
bool visited[totalSize];
memset(visited, false, sizeof(visited));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
int idx = i * n + j;
if (grid[i][j] && !visited[idx]) {
counter = 0;
q.push(idx);
visited[idx] = true;
while (!q.empty()) {
int pos = q.front();
q.pop();
counter++;
int x = pos / n;
int y = pos % n;
for (int k = 0; k < 4; ++k) {
int nx = x + dx[k];
int ny = y + dy[k];
idx = nx * n + ny;
if (nx > 0 && nx < m - 1 && ny > 0 && ny < n - 1 && !visited[idx] && grid[nx][ny]) {
visited[idx] = true;
q.push(idx);
}
}
}
maxRes = max(maxRes, counter);
}
}
}
return maxRes;
}
遍历每一个 grid 内的点
如果这个点 是 1 并且未被 visit, 从这个点开始 dfs
这个点本身的 count 是 1
并且 count += 周围符合条件的点的 dfs 的结果
最后返回 count
取 不同 起点的 dfs 都最大值作为 result
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
visited = [[0 for _ in range(n)] for _ in range(m)]
max_area = 0
def dfs(i, j, count):
directions = [(0,1),(1,0),(0,-1),(-1,0)]
if visited[i][j] == 1:
return
visited[i][j] = 1
if grid[i][j] == 1:
count += 1
for d1, d2 in directions:
i1, j1 = i + d1, j + d2
if i1 < 0 or i1 >= m or j1 < 0 or j1 >= n:
continue
if visited[i1][j1] == 1:
continue
if grid[i][j] == 0:
continue
count = dfs(i1, j1, count)
return count
for i in range(m):
for j in range(n):
# if not visited yet
if visited[i][j] == 0:
max_area = max(max_area, dfs(i, j, 0))
return max_area
m, n 为 grid 的行 和 列数
时间复杂度: O(mn) 每个点最多 dfs visit 一次
空间复杂度: O(mn) 递归深度最大是 O(mn) visited 数组的复杂度也是 O(mn)
Language: Java
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int max = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
max = Math.max(max, getIslandArea(i, j, grid));
}
}
return max;
}
private int getIslandArea(int i, int j, int[][] grid) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) {
return 0;
}
grid[i][j] = 0;
return 1 + getIslandArea(i - 1, j, grid) + getIslandArea(i + 1, j, grid) + getIslandArea(i, j - 1, grid)
+ getIslandArea(i, j + 1, grid);
}
}
递归,dfs
C++ Code:
class Solution {
public:
int backtrack(vector<vector<int>>& grid, int i, int j){
if(i < 0 || i>=grid.size())return 0;
if(j < 0 || j>=grid[0].size())return 0;
if(grid[i][j] == 1){
grid[i][j] = 0;
return 1 + backtrack(grid,i-1,j) + backtrack(grid,i+1,j) + backtrack(grid,i,j-1) + backtrack(grid,i,j+1);
}
return 0;
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int temparea = 0;
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){
temparea = backtrack(grid,i,j);
maxarea = maxarea > temparea ? maxarea:temparea;
}
}
}
return maxarea;
}
};
复杂度分析
import "math"
func maxAreaOfIsland(grid [][]int) int {
res := 0.0
for i := 0; i < len(grid); i++ {
for j := 0; i < len(grid[i]); j++ {
if grid[i][j] == 1 {
res = math.Min(float64(res), float64(dfs(i, j, grid)))
}
}
}
return int(res)
}
func dfs(i int, j int, grid [][]int) (num int) {
// 越界时直接返回0
if i < 0 || j < 0 || i >= len(grid)-1 || j >= len(grid[i])-1 {
return 0
}
// 将找到的岛屿改成0
grid[i][j] = 0
num = 1
// 右
num += dfs(i+1, j, grid)
// 左
num += dfs(i+1, j, grid)
// 上
num += dfs(i, j+1, grid)
// 下
num += dfs(i, j-1, grid)
return num
}
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int max = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
max = Math.max(max, getIslandArea(i, j, grid));
}
}
return max;
}
private int getIslandArea(int i, int j, int[][] grid) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) {
return 0;
}
grid[i][j] = 0;
return 1 + getIslandArea(i - 1, j, grid) + getIslandArea(i + 1, j, grid) + getIslandArea(i, j - 1, grid)
+ getIslandArea(i, j + 1, grid);
}
}
dfs
``
class Solution {
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) {
int cur = 0;
Deque<Integer> stacki = new LinkedList<Integer>();
Deque<Integer> stackj = new LinkedList<Integer>();
stacki.push(i);
stackj.push(j);
while (!stacki.isEmpty()) {
int cur_i = stacki.pop(), cur_j = stackj.pop();
if (cur_i < 0 || cur_j < 0 || cur_i == grid.length || cur_j == grid[0].length || grid[cur_i][cur_j] != 1) {
continue;
}
++cur;
grid[cur_i][cur_j] = 0;
int[] di = {0, 0, 1, -1};
int[] dj = {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 = Math.max(ans, cur);
}
}
return ans;
}
}
时间复杂度:O(n*m),n是行,m是列
空间复杂度:O(n*m)
/**
* @param {number[][]} grid
* @return {number}
*/
var maxAreaOfIsland = function(grid) {
let res = 0;
for(let i = 0; i < grid.length; i++) {
for(let j = 0; j < grid[0].length; j++) {
res = Math.max(dfs(grid, i, j), res)
}
}
return res;
};
const dfs = (grid, i, j) => {
if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length) {
return 0
}
if (grid[i][j] === 1) {
grid[i][j] = 0;
return 1 + dfs(grid, i - 1, j) + dfs(grid, i + 1, j) + dfs(grid, i , j - 1) + dfs(grid, i, j + 1)
}
return 0
}
时间:O(i * j);
空间:O(i * j)
int maxAreaOfIsland(vector<vector<int>>& grid) {
int res = 0;
for (int i = 0; i < grid.size(); ++i) {
for (int j = 0; j < grid[0].size(); ++j) {
res = max(res, dfs(grid, i, j));
}
}
return res;
}
int dfs(vector<vector<int>>& grid, int i, int j) {
//搜索到达矩阵边界或为0
if (i < 0 || j < 0 || i == grid.size() || j == grid[0].size() || grid[i][j] != 1) {
return 0;
}
//标记为0,避免重复
grid[i][j] = 0;
int res = 1;
//从四个方向递归
vector<vector<int>> direction = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };
for (int index = 0; index < 4; ++index) {
int nexti = i + direction[index][0], nextj = j + direction[index][1];
res += dfs(grid, nexti, nextj);
}
return res;
}
dfs
class Solution {
int maxCount = 0;
int sum;
public int maxAreaOfIsland(int[][] grid) {
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid[0].length; j++) {
if(grid[i][j] == 1) {
sum = 0;
dfs(i, j, grid);
}
}
}
return maxCount;
}
private void dfs(int i, int j, int[][] grid) {
if(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == 0)
return;
sum += 1;
maxCount = Math.max(maxCount, sum);
grid[i][j] = 0;
dfs(i + 1, j, grid);
dfs(i - 1, j, grid);
dfs(i, j + 1, grid);
dfs(i, j - 1, grid);
}
}
m == grid.length
n == grid[i].length
1 <= m, n <= 50
grid[i][j] is either 0 or 1.
connected 4-directionally (horizontal or vertical.)
Return the maximum area of an island in grid. If there is no island, return 0.
https://leetcode-cn.com/problems/max-area-of-island/solution/695-dao-yu-de-zui-da-mian-ji-dfspython3-by-fe-luci/
same with 200 number of islands, when we do dfs, we keep track of area
get the max area
Time: O(m*n)
Space: O(m*n)
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int maxArea = 0;
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[0].length; c++) {
if (grid[r][c] != 0) {
int[] curArea = new int[1];
dfs(grid, r, c, curArea);
maxArea = Math.max(curArea[0], maxArea);
}
}
}
return maxArea;
}
private void dfs(int[][] grid, int curRow, int curCol, int[] curArea) {
if (curRow < 0 || curRow >= grid.length || curCol < 0 || curCol >= grid[0].length || grid[curRow][curCol] == 0) {
return;
}
// mark
grid[curRow][curCol] = 0;
curArea[0] += 1;
dfs(grid, curRow - 1, curCol, curArea);
dfs(grid, curRow + 1, curCol, curArea);
dfs(grid, curRow, curCol - 1, curArea);
dfs(grid, curRow, curCol + 1, curArea);
}
}
DFS
- 从陆地出发,遍历该陆地所在的岛屿
- 从隶属于该岛屿的某一块陆地出发,向四个方向递归地进行DFS
- 每次递归对下标进行判断,以区域的边界作为递归边界
- 将已访问过的陆地置为0,以保证每块陆地只访问一次
- 递归地返回整块岛屿陆地面积
- 找出所有岛屿的最大值
javaScript
/**
* @param {number[][]} grid
* @return {number}
*/
var maxAreaOfIsland = function(grid) {
let x = grid.length;
let y = grid[0].length;
let max = 0;
// 遍历二维数组
for (let i = 0; i < x; i ++) {
for (let j = 0; j < y; j ++) {
if (grid[i][j] === 1) {
max = Math.max(max, areaOfIsland(grid, i, j, x, y));
}
}
}
return max;
};
var areaOfIsland = function(grid, i, j, x, y) {
// 判断边界条件
if(i < 0 || i >= x || j < 0 || j >= y || grid[i][j] === 0) {
return 0
}
let ans = 1;
// 将遍历过的岛屿标记为0
grid[i][j] = 0;
// 遍历岛屿四周
ans += areaOfIsland(grid, i + 1, j, x, y);
ans += areaOfIsland(grid, i - 1, j, x, y);
ans += areaOfIsland(grid, i, j + 1, x, y);
ans += areaOfIsland(grid, i, j - 1, x, y);
return ans;
}
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
for(int r = 0; r < grid.length; r++){
for(int c = 0; c < grid[0].length; c++){
if(grid[r][c] == 1){
int a = dfs(grid, r, c);
res = Math.max(res, a);
}
}
}
return res;
}
public int dfs(int[][] grid, int r, int c){
// 如果这个格子超过界限,直接返回
if(!inArea(grid, r, c)){
return 0;
}
// 如果这个格子不是岛屿,直接返回
if(grid[r][c] != 1){
return 0;
}
// 将格子标记为「已遍历过」
grid[r][c] = 2;
//每遍历到一个格子,就把面积加一
// 访问上、下、左、右四个相邻结点
return 1
+ dfs(grid, r - 1, c)
+ dfs(grid, r + 1, c)
+ dfs(grid, r, c - 1)
+ dfs(grid, r, c + 1);
}
// 判断坐标 (r, c) 是否在网格中
public boolean inArea(int[][] grid, int r, int c){
return 0 <= r && r < grid.length && 0 <= c && c < grid[0].length;
}
}
class Solution { public int maxAreaOfIsland(int[][] grid) { int max = 0; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { max = Math.max(max, getIslandArea(i, j, grid)); } } return max; }
private int getIslandArea(int i, int j, int[][] grid) {
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) {
return 0;
}
grid[i][j] = 0;
return 1 + getIslandArea(i - 1, j, grid) + getIslandArea(i + 1, j, grid) + getIslandArea(i, j - 1, grid)
+ getIslandArea(i, j + 1, grid);
}
}
广度优先搜索
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
row, col = len(grid), len(grid[0])
ret = 0
for i in range(row):
for j in range(col):
if grid[i][j] == 0:
continue
dq, cur = deque([(i,j)]), 1
while dq:
x, y = dq.popleft()
grid[x][y] = 0
choices = [[0, -1], [0, 1], [-1, 0], [1, 0]]
for choice in choices:
nx, ny = x + choice[0], y + choice[1]
if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == 1:
cur += 1
grid[nx][ny] = 0
dq.append((nx, ny))
ret = max(ret, cur)
return ret
class Solution: def maxAreaOfIsland(self, grid: List[List[int]]) -> int: m = len(grid) if m == 0: return 0 n = len(grid[0]) ans = 0 def dfs(i, j): if i < 0 or i >= m or j < 0 or j >= n: return 0 if grid[i][j] == 0: return 0 grid[i][j] = 0 top = dfs(i + 1, j) bottom = dfs(i - 1, j) left = dfs(i, j - 1) right = dfs(i, j + 1) return 1 + sum([top, bottom, left, right])
for i in range(m):
for j in range(n):
ans = max(ans, dfs(i, j))
return ans
# 0 m*n 0 m*n
class Solution:
def dfs(self, grid, cur_i, cur_j) -> int:
if cur_i < 0 or cur_j < 0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] != 1:
return 0
grid[cur_i][cur_j] = 0
ans = 1
for di, dj in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
next_i, next_j = cur_i + di, cur_j + dj
ans += self.dfs(grid, next_i, next_j)
return ans
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
for i, l in enumerate(grid):
for j, n in enumerate(l):
ans = max(self.dfs(grid, i, j), ans)
return ans
BFS
代码
class Solution: def maxAreaOfIsland(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) def bfs(i, j): queue = [(i, j)] grid[i][j] = 0 area = 1 while queue: x, y = queue.pop(0) for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n and grid[nx][ny]: grid[nx][ny] = 0 area += 1 queue.append((nx, ny)) return area res = 0 for i in range(m): for j in range(n): if grid[i][j]: res = max(res, bfs(i, j)) return res
复杂度
时间:O(m*n)
空间:O(m*n)
var maxAreaOfIsland = function(grid) {
let x=grid[0].length,y=grid.length;
let res=0;
function dfs(i,j){
// i 是y ,j是x
if(i>=y||j>=x||j<0||i<0||grid[i][j]!=1)return 0;
grid[i][j]=-1;
return 1+dfs(i+1,j)+dfs(i-1,j)+dfs(i,j-1)+dfs(i,j+1);
}
for(let i=0;i<y;i++){
// i 是y ,j是x
for(let j=0;j<x;j++){
if(grid[i][j]){
res=Math.max(res, dfs(i,j))
}
}
}
return res
};
DFS
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m = len(grid)
if m == 0: return 0
n = len(grid[0])
ans = 0
def dfs(i, j):
if i < 0 or i >= m or j < 0 or j >= n: return 0
if grid[i][j] == 0: return 0
grid[i][j] = 0
top = dfs(i + 1, j)
bottom = dfs(i - 1, j)
left = dfs(i, j - 1)
right = dfs(i, j + 1)
return 1 + sum([top, bottom, left, right])
for i in range(m):
for j in range(n):
ans = max(ans, dfs(i, j))
return ans
时间复杂度:O(M*N)
空间复杂度:O(M*N)
var maxAreaOfIsland = function(grid) {
const row = grid.length, col = grid[0].length
let res = 0
const DFS = (i, j) => {
if (i < 0 || i >= row || j < 0 || j >= col) {
return 0
}
if(grid[i][j] == 0) {
return 0
}
grid[i][j] = 0
return 1 + DFS(i, j-1) + DFS(i-1, j) + DFS(i, j+1) + DFS(i+1, j)
}
for(let i=0; i<row; i++) {
for(let j=0; j<col; j++) {
if (grid[i][j] == 1) {
res = Math.max(res, DFS(i,j))
} else {
continue
}
}
}
return res
};
dfs. need to set the visited grid[i][j]=0
Time: O(mn) Space: O(mn) (due to recursion)
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int max=0;
for(int i=0;i<grid.length;i++) {
for(int j=0;j<grid[i].length;j++) {
if(grid[i][j]==1) {
max=Math.max(max,dfs(grid,i,j));
}
}
}
return max;
}
public 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 count=1;
grid[i][j]=0;
int[] x_axis = {0,0,1,-1};
int[] y_axis = {1,-1,0,0};
for(int k=0;k<4;k++) {
int next_x=i+x_axis[k];
int next_y=j+y_axis[k];
count+=dfs(grid,next_x,next_y);
}
return count;
}
}
DFS模版题了吧。当遇到grid[i][j] =1的时候上下左右继续dfs它,然后保留最大值就行了。
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
row, col = len(grid),len(grid[0])
res = 0
def dfs(i,j):
if 0 <= i < row and 0 <= j < col and grid[i][j] == 1:
# 防止重复计数
grid[i][j] = 0
return 1 + dfs(i+1,j) + dfs(i-1,j) + dfs(i,j+1) + dfs(i,j-1)
else:
return 0
return max(dfs(i,j) for i in range(row) for j in range(col))
Time complexity: O(row col) Space complexity: O(row col)
var maxAreaOfIsland = function(grid) {
const row = grid.length, col = grid[0].length
let res = 0
const DFS = (i, j) => {
if (i < 0 || i >= row || j < 0 || j >= col) {
return 0
}
if(grid[i][j] == 0) {
return 0
}
grid[i][j] = 0
return 1 + DFS(i, j-1) + DFS(i-1, j) + DFS(i, j+1) + DFS(i+1, j)
}
for(let i=0; i<row; i++) {
for(let j=0; j<col; j++) {
if (grid[i][j] == 1) {
res = Math.max(res, DFS(i,j))
} else {
continue
}
}
}
return res
};
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m_s :int = 0
m = len(grid)
n = len(grid[0])
t :int = 0
def infection(i,j):
nonlocal t
nonlocal grid
nonlocal m_s
if i>-1 and i< m and j>-1 and j<n and grid[i][j] == 1:
t+=1
grid[i][j] = 0
infection(i-1,j)
infection(i+1,j)
infection(i,j-1)
infection(i,j+1)
if m_s < t:
m_s = t
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
t = 0
infection(i,j)
return m_s
DFS
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
def dfs(grid, i, j):
if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]) or grid[i][j] == 0:
return 0
area = 1
grid[i][j] = 0
area += dfs(grid, i + 1, j)
area += dfs(grid, i - 1, j)
area += dfs(grid, i, j - 1)
area += dfs(grid, i, j + 1)
return area
ans = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == 1:
ans = max(ans, dfs(grid, i, j))
return ans
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length, n = grid[0].length, maxArea = 0;
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
if (grid[i][j] == 1){
maxArea = Math.max(maxArea, dfs(grid, i, j, m, n));
}
}
}
return maxArea;
}
private int dfs(int[][] grid, int i, int j, int m, int n){
if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] == 0) return 0;
int area = 0;
grid[i][j] = 0;
area = 1 + dfs(grid, i + 1, j, m, n) +
+ dfs(grid, i - 1, j, m, n) +
+ dfs(grid, i, j + 1, m, n) +
+ dfs(grid, i, j - 1, m, n);
return area;
}
}
Time Complexity: O(m n), Space Complexity: O(m n)
Using DFS.
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans, n, m = 0, len(grid), len(grid[0])
def trav(i: int, j: int) -> int:
if i < 0 or j < 0 or i >= n or j >= m or grid[i][j] == 0: return 0
grid[i][j] = 0
return 1 + trav(i-1, j) + trav(i, j-1) + trav(i+1, j) + trav(i, j+1)
for i, j in product(range(n), range(m)):
if grid[i][j]: ans = max(ans, trav(i, j))
return ans
Time complexity: O(m n).
Space complexity: O(m n).
小岛问题模板,递归地进行多点搜索,并且用标记grid的技巧,把访问过的标记为-1,这题来说标记为0也可以的,因为我们只看值为1的grid块。这题不需要撤销标记。
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
if not grid:
return 0
m, n = len(grid), len(grid[0])
def dfs(cur_i, cur_j):
if cur_i < 0 or cur_i >= m or cur_j < 0 or cur_j >= n or grid[cur_i][cur_j] != 1:
return 0
grid[cur_i][cur_j] = -1 # 标记为搜索过了,这里也可以是0
res = 1
for di, dj in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
res += dfs(cur_i+di, cur_j+dj)
return res
res = 0
for i in range(m):
for j in range(n):
res = max(res, dfs(i, j))
return res
DFS + 采用原位修改的方式避免记录 visited 的开销
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
const int m = grid.size(), n = grid[0].size();
int ans = 0;
function<int(int, int)> dfs = [&](int i, int j)->int{
if(i < 0 || j < 0 || i >= m || j >= n)
return 0;
if(grid[i][j] == 0)
return 0;
grid[i][j] = 0;
return 1 + dfs(i-1, j) + dfs(i+1, j) + dfs(i, j-1) + dfs(i, j+1);
};
for(int i = 0; i < m; ++i){
for(int j = 0; j < n; ++j){
if(grid[i][j])
ans = max(ans, dfs(i, j));
}
}
return ans;
}
};
T: O(mn) S: O(mn) 递归的深度最大可能是整个网格的大小,因此最大可能使用 O(mn) 的栈空间。
相似题:200
def dfs(self, grid, cur_i, cur_j) -> int:
if cur_i < 0 or cur_j < 0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j] != 1:
return 0
grid[cur_i][cur_j] = 0
ans = 1
for di, dj in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
next_i, next_j = cur_i + di, cur_j + dj
ans += self.dfs(grid, next_i, next_j)
return ans
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
for i, l in enumerate(grid):
for j, n in enumerate(l):
ans = max(self.dfs(grid, i, j), ans)
return ans
时间复杂度:O(MN) 空间复杂度:O(MN)
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
max_area = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] ==1:
grid[i][j] = 2
temp = 1
queue = collections.deque([(i,j)])
while queue:
x,y = queue.popleft()
for a,b in [(x+1,y),(x-1,y),(x,y+1),(x,y-1)]:
if a>-1 and b>-1 and a< len(grid) and b< len(grid[0]):
if grid[a][b] == 1:
queue.append((a,b))
grid[a][b] =2
#print(a,b)
temp+=1
#print(temp,max_area)
max_area = max(temp,max_area)
return max_area
class Solution {
int[] deltX = new int[]{0, 0, 1, -1};
int[] deltY = new int[]{1, -1, 0, 0};
public int maxAreaOfIsland(int[][] grid) {
Set<Integer> visited = new HashSet();
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
int start = i * grid[0].length + j;
if (grid[i][j] == 1 && !visited.contains(start)) {
visited.add(start);
int area = helper(visited, grid, start);
//System.out.println("area = " + area + " x = " + i + " y =" + j);
res = Math.max(res, area);
}
}
}
return res;
}
private int helper(Set<Integer> visited, int[][] grid, int start) {
Queue<Integer> fringe = new ArrayDeque();
int res = 0;
fringe.add(start);
while (!fringe.isEmpty()) {
int cur = fringe.poll();
res++;
for (int neighbor : neighbors(cur, grid)) {
if (visited.contains(neighbor)) {
continue;
}
visited.add(neighbor);
fringe.offer(neighbor);
}
}
return res;
}
private Set<Integer> neighbors(int cur, int[][] grid) {
int curx = cur / grid[0].length;
int cury = cur % grid[0].length;
Set<Integer> res = new HashSet();
for (int i = 0; i < 4; i++) {
int x = curx + deltX[i];
int y = cury + deltY[i];
if (x >= 0 && x < grid.length && y >= 0 && y < grid[0].length && grid[x][y] == 1) {
res.add(x * grid[0].length + y);
}
}
return res;
}
}
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
if not grid:
return 0
visited = set()
result = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == 1 and (i, j) not in visited:
result = max(result, self.dfs(grid, visited, i, j))
return result
def dfs(self, grid, visited, i, j):
if not self.is_valid(grid, visited, i, j):
return 0
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
result = 1
visited.add((i, j))
for delta_x, delta_y in directions:
next_x = delta_x + i
next_y = delta_y + j
result += self.dfs(grid, visited, next_x, next_y)
return result
def is_valid(self, grid, visited, i, j):
if i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0]):
return False
if (i, j) in visited:
return False
if grid[i][j] == 0:
return False
return True
class Solution:
def maxAreaOfIsland(self, g: List[List[int]]) -> int:
m, n = len(g), len(g[0])
def dfs(x, y):
g[x][y] = -1
res = 0
for dx, dy in [[-1,0], [1,0], [0,1], [0,-1]]:
xx = x + dx
yy = y + dy
if m > xx >= 0 and n > yy >= 0 and g[xx][yy] == 1:
res += dfs(xx, yy)
return res + 1
c = 0
for i in range(m):
for j in range(n):
if g[i][j] == 1:
c = max(c, dfs(i, j))
return c
Time: O(n^2)
Space: O(n^2)
https://leetcode-cn.com/problems/max-area-of-island/
DFS
class Solution {
boolean seen[][];
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
int rows = grid.length;
int cols = grid[0].length;
seen = new boolean[rows][cols];
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
res = Math.max(res, dfs(i, j, grid));
}
}
return res;
}
private int dfs(int row, int col, int[][] grid) {
if(row < 0 || row >= grid.length || col < 0 || col >= grid[row].length || seen[row][col] || grid[row][col] == 0) {
return 0;
}
seen[row][col] = true;
return 1 + dfs(row + 1, col, grid)+ dfs(row - 1, col, grid) + dfs(row, col + 1, grid) + dfs(row, col - 1, grid);
}
}
O(N^2)
O(N^2)
DFS。对二维数组进行遍历,遇到陆地(值为1)的时候开始DFS搜索周围4个方向,看是否有连成片的陆地,同时将该位置的值设为0,记为已经访问过,避免重复。以此为基础将DFS进行下去,直到周围没有陆地为止,这样就求出了陆地的面积。遍历的时候不断更新最大值。遍历结束返回即为结果。
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int m = grid.length, n = grid[0].length;
int max = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0) continue;
max = Math.max(max, dfs(grid, i, j));
}
}
return max;
}
private int dfs(int[][] grid, int row, int col) {
int m = grid.length, n = grid[0].length;
// index not valid
if (row < 0 || row >= m || col < 0 || col >= n) return 0;
// visited or in water
if (grid[row][col] == 0) return 0;
// marked current land as visited
grid[row][col] = 0;
return 1 + dfs(grid, row - 1, col) + dfs(grid, row + 1, col) + dfs(grid, row, col - 1) + dfs(grid, row, col + 1);
}
}
复杂度分析
const dfs = (grid, i, j) => {
let m = grid.length,
n = grid[0].length;
if (i < 0 || j < 0 || i >= m || j >= n) {
// 超出索引边界
return 0;
}
if (grid[i][j] == 0) {
// 已经是海水了
return 0;
}
// 将 (i, j) 变成海水
grid[i][j] = 0;
// 淹没上下左右的陆地
return (
dfs(grid, i + 1, j) + // 上
dfs(grid, i - 1, j) + // 下
dfs(grid, i, j - 1) + // 左
dfs(grid, i, j + 1) + // 右
1
);
};
/**
* @param {number[][]} grid
* @return {number}
*/
var maxAreaOfIsland = function (grid) {
let m = grid.length,
n = grid[0].length;
// 记录岛屿的最大面积
let count = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] == 1) {
// 淹没岛屿,并更新最大岛屿面积
count = Math.max(count, dfs(grid, i, j));
}
}
}
return count;
};
BFS 反复遍历 上下左右
var maxAreaOfIsland = function(grid) {
let row = grid.length
let colums = grid[0].length
let max = 0
function dfs(i,j){
if(i<0||i>=row||j<0||j>=colums||grid[i][j]!=1) return 0
grid[i][j]=0
let count =1
count+=dfs(i-1,j)+dfs(i+1,j)+dfs(i,j+1)+dfs(i,j-1)
return count
}
for(let i = 0;i<row;i++){
for(let j = 0;j<colums;j++){
max = Math.max(max,dfs(i,j))
}
}
return max
};
思路
(补卡)dfs搜索上下左右,并走过的地点进行标记,保存最大值
代码
public int maxAreaOfIsland(int[][] grid){
int ret = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] == 0){
continue;
}
ret = Math.max(ret,dfs(grid,i,j));
}
}
return ret;
}
private int dfs(int[][] grid, int row, int col) {
int n = grid.length;
int m = grid[0].length;
if (row > n || row < 0 || col > m || col < 0){
return 0;
}
if (grid[row][col] == 0){
return 0;
}
grid[row][col] = 0;
return 1 + dfs(grid,row - 1,col) + dfs(grid,row + 1,col) + dfs(grid,row,col - 1) + dfs(grid,row,col + 1);
}
复杂度
时间复杂度:O(M*N)
空间复杂度:O(M*N)
class Solution: def maxAreaOfIsland(self, grid: List[List[int]]) -> int: self.grid = grid self.m = len(grid) if self.m == 0: return 0 self.n = len(grid[0]) ans = 0 for i in range(self.m): for j in range(self.n): ans = max(ans, self.bfs(i,j)) return ans
def bfs(self, i, j):
q = collections.deque()
q.append((i,j))
current = 0
while q:
i, j = q.popleft()
if i < 0 or i >= self.m or j < 0 or j >= self.n:
continue
if self.grid[i][j] == 0:
continue
current += 1
self.grid[i][j] = 0
q.append((i + 1,j))
q.append((i - 1, j))
q.append((i, j - 1))
q.append((i, j + 1))
return current
Start from each island, visit its neighbor islands, after visits, mark the island as 0 so that we don't need to use a visited matrix.
class Solution {
public:
vector<pair<int, int>> steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int scanIsland(vector<vector<int>>& grid, int i, int j) {
int count = 0;
queue <pair<int, int>> worker;
worker.push(make_pair(i, j));
grid[i][j] = 0;
while (!worker.empty()) {
int x = worker.front().first;
int y = worker.front().second;
worker.pop();
count++;
for (auto& step : steps) {
int a = x + step.first;
int b = y + step.second;
if (a < 0 || a >= grid.size() || b < 0 || b >= grid[0].size() || grid[a][b] == 0)
continue;
worker.push(make_pair(a, b));
grid[a][b] = 0;
}
}
return count;
}
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++) {
if (grid[i][j] == 1) {
int num = scanIsland(grid, i, j);
ans = ans < num ? num : ans;
}
}
return ans;
}
};
O(m*n), we need to at most visit each node once.
O(1), we don't need to use any extra storage.
方法 在求得小岛数量的基础上增加计算面积的功能 代码
实现语言: C++
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int maxx = 0;
for(int i = 0;i < grid.size();i++){
for(int j = 0; j< grid[0].size();j++)
{
maxx = max(maxx, getIslandarea(i,j,grid));
}
}
return maxx;
}
private:
int getIslandarea(int i, int j, vector<vector<int>>& grid)
{
if(i < 0 || i >= grid.size() || j >= grid[0].size() || grid[i][j] == 0)
{
return 0;
}
grid[i][j] = 0;
return 1 + getIslandarea(i - 1, j, grid)+getIslandarea(i + 1, j, grid)+getIslandarea(i, j + 1, grid)+getIslandarea(i, j - 1, grid);
}
};
复杂度分析 时间复杂度: O(mn) 空间复杂度: O(mn)
class Solution
{
public:
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
int maxAreaOfIsland(vector<vector<int>>& grid)
{
int m = grid.size(), n = grid[0].size(), res = 0;
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
if (grid[i][j] == 1)
{
res = max(res, dfs(grid, i, j));
}
}
}
return res;
}
int dfs(vector<vector<int>>& grid, int i, int j)
{
int res = 1;
grid[i][j] = 0;
int m = grid.size(), n = grid[0].size();
for(int k = 0; k < 4; k++)
{
int tmp_x = i + dx[k];
int tmp_y = j + dy[k];
if(tmp_x >= 0 && tmp_x < m && tmp_y >=0 && tmp_y < n)
{
if(grid[tmp_x][tmp_y])
res += dfs(grid, tmp_x, tmp_y);
}
}
return res;
}
};
++
给你一个大小为 m x n
的二进制矩阵 grid
。
岛屿 是由一些相邻的 1
(代表土地) 构成的组合,这里的「相邻」要求两个 1
必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid
的四个边缘都被 0
(代表水)包围着。
岛屿的面积是岛上值为 1
的单元格的数目。
计算并返回 grid
中最大的岛屿面积。如果没有岛屿,则返回面积为 0
。
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int res = 0;
for(int i = 0; i < grid.size(); i++){
for(int j = 0; j < grid[0].size(); j++){
if(grid[i][j] == 1)
{
res = max(res, dfs(grid, i, j));
}
}
}
return res;
}
private:
int dfs(vector<vector<int>>& grid, int i, int j){
// 不是1,则需要返回0
if(i < 0 || i >= grid.size() || j < 0 || j >= grid[0].size() || grid[i][j] == 0){
return 0;
}
// 是1, 需要dfs
grid[i][j] = 0; // 设置为0, 避免重复访问
int num = 1;
num += dfs(grid, i + 1, j);
num += dfs(grid, i - 1, j);
num += dfs(grid, i, j + 1);
num += dfs(grid, i, j - 1);
return num;
}
};
695. 岛屿的最大面积
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/max-area-of-island/
前置知识
暂无
题目描述