leetcode-pp / 91alg-5-daily-check

91 天学算法第五期打卡
55 stars 14 forks source link

【Day 50 】2021-10-29 - 695. 岛屿的最大面积 #68

Open azl397985856 opened 3 years ago

azl397985856 commented 3 years ago

695. 岛屿的最大面积

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/max-area-of-island/

前置知识

暂无

题目描述

给定一个包含了一些 0 和 1 的非空二维数组 grid 。
一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,
这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。
你可以假设 grid 的四个边缘都被 0(代表水)包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 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
wangyifan2018 commented 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
chakochako commented 3 years ago
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
laurallalala commented 3 years ago

代码

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)

hellowxwworld commented 3 years ago

思路

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;
        }
joeytor commented 3 years ago

思路

遍历每一个 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)

BlueRui commented 3 years ago

Problem 695. Max Area of Island

Algorithm

Complexity

Code

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);
    }
}
Maschinist-LZY commented 3 years ago

思路

递归,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;   
    }
};

复杂度分析

guangsizhongbin commented 3 years ago
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
}
jinmenghan commented 3 years ago
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);
    }
}
ymkymk commented 3 years ago

思路

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)

winterdogdog commented 3 years ago

DFS

/**
 * @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
}

复杂度分析

mokrs commented 3 years ago
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;
}
mmboxmm commented 3 years ago

思路

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);
    }
}
taojin1992 commented 3 years ago

Understand:

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.

Plan & Match:

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

Evaluate:

Time: O(m*n)
Space: O(m*n)

Code

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);
    }
}
liuajingliu commented 3 years ago

解题思路

DFS

  1. 从陆地出发,遍历该陆地所在的岛屿
    • 从隶属于该岛屿的某一块陆地出发,向四个方向递归地进行DFS
    • 每次递归对下标进行判断,以区域的边界作为递归边界
    • 将已访问过的陆地置为0,以保证每块陆地只访问一次
    • 递归地返回整块岛屿陆地面积
  2. 找出所有岛屿的最大值

代码实现

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;
}

复杂度分析

flame0409 commented 3 years ago
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;
    }
}
moxiaopao278 commented 3 years ago

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);
}

}

BreezePython commented 3 years ago

思路

广度优先搜索

代码

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

复杂度

Richard-LYF commented 3 years ago

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
Lydia61 commented 3 years ago

岛屿的最大面积

思路

代码

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

复杂度分析

Tomtao626 commented 3 years ago

思路

QiZhongdd commented 3 years ago
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
};
yibenxiao commented 3 years ago

【Day 50】695. 岛屿的最大面积

思路

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)

zyMacro commented 3 years ago
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
};
pan-qin commented 3 years ago

idea

dfs. need to set the visited grid[i][j]=0

Complexity

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;
    }
}
Venchyluo commented 3 years ago

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)

lihuiwen commented 3 years ago

代码

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
};
ChenJingjing85 commented 3 years ago
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
Auto-SK commented 3 years ago

思路

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

复杂度

xj-yan commented 3 years ago
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)

LareinaWei commented 3 years ago

Thinking

Using DFS.

Code

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

Complexity

Time complexity: O(m n).
Space complexity: O(m
n).

naomiwufzz commented 3 years ago

思路:dfs

小岛问题模板,递归地进行多点搜索,并且用标记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

复杂度分析

JianXinyu commented 3 years ago

思路

DFS + 采用原位修改的方式避免记录 visited 的开销

Code

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

biscuit279 commented 3 years ago

思路 DFS

    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)

zjsuper commented 3 years ago

bfs

pay attention to the boundary

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
Huangxuang commented 3 years ago

题目:[695. Max Area of Island](https://leetcode-cn.com/problems/max-area-of-island/)

思路

代码

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;
    }
}

复杂度分析

biancaone commented 3 years ago
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
littlemoon-zh commented 3 years ago

day 50

695. Max Area of Island

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)

RocJeMaintiendrai commented 3 years ago

题目

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)

chenming-cao commented 3 years ago

解题思路

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);
    }
}

复杂度分析

wenlong201807 commented 3 years ago

代码块


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;
};

时间复杂度和空间复杂度

lilixikun commented 3 years ago

思路

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
};

复杂度

JK1452470209 commented 3 years ago

思路

(补卡)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)

liudi9047 commented 3 years ago

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
shixinlovey1314 commented 3 years ago

Title:695. Max Area of Island

Question Reference LeetCode

Solution

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.

Code

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;
    }
};

Complexity

Time Complexity and Explanation

O(m*n), we need to at most visit each node once.

Space Complexity and Explanation

O(1), we don't need to use any extra storage.

Bingbinxu commented 3 years ago

方法 在求得小岛数量的基础上增加计算面积的功能 代码

实现语言: 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)

ccslience commented 3 years ago
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;
    }
};
dahaiyidi commented 2 years ago

Problem

695. 岛屿的最大面积

++

给你一个大小为 m x n 的二进制矩阵 grid

岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

岛屿的面积是岛上值为 1 的单元格的数目。

计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0


Note


Complexity


Python

C++

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;
    }
};

From : https://github.com/dahaiyidi/awsome-leetcode