java数据结构与算法刷题-----LeetCode695. 岛屿的最大面积

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

在这里插入图片描述

1. 深度优先遍历

这不是找最短路径,而是找面积,所以深度优先更适合。

解题思路:时间复杂度O( r ∗ c r*c rc)r和c表示行列个数,也就是整张二维地图都遍历一边,空间复杂度O( r ∗ c r*c rc)
  1. 一行一行的遍历地图,如果发现当前结点 = 1表示陆地,就从当前坐标开始进行深度优先遍历
  2. 遍历过的结点将其标记为已访问,然后朝向上下左右四个方向依次继续深度优先遍历,并将结果相加。
代码

在这里插入图片描述

class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        int max = 0;//保存答案
        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[0].length; c++) {//遍历地图
                if(grid[r][c]==1){//如果是陆地,就进入深度优先遍历,统计其陆地大小
                    int res = dfs(grid,r,c);//dfs
                    max = Math.max(max,res);//如果当前陆地更大,就保存其为答案
                }
            }
        }
        return max;//返回最大陆地大小
    }
    //深度优先遍历
    int dfs(int[][] grid,int r,int c){
        int m = grid.length,n = grid[0].length;//地图边界
        if(r<0||c<0||r>=m||c>=n) return 0;//如果当前坐标不在地图中,返回0,表示当前坐标陆地面积为0

        if(grid[r][c]!=1) return 0;//如果当前坐标在地图中,但是是海洋(0)或者已经统计过的陆地(2)的话,也返回0表示当前坐标陆地面积为0
        grid[r][c]=2;//如果当前坐标是陆地,将其置为2,表示已经访问过
        //然后从当前坐标向4个方向走一步继续统计。
        return 1+dfs(grid,r-1,c)+dfs(grid,r+1,c)+dfs(grid,r,c-1)+dfs(grid,r,c+1);
    }

}

2. 广度优先

这题不太适合广度优先,代码会比较多,没有深度优先遍历简洁,并且需要使用Java自带容器Queue,会比深度优先遍历的底层栈空间慢很多

解题思路:时间复杂度O( r ∗ c r*c rc),空间复杂度O( r ∗ c r*c rc)
  1. 和法一深度优先遍历一样,就是将代码转换为广度优先而已
代码

在这里插入图片描述

class Solution {
    int[][] grid;//保存地图
    int m,n;//地图边界
    final int[][] directions = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};//方向参数,上下右左
    public int maxAreaOfIsland(int[][] grid) {
        this.grid = grid;
        this.m = grid.length; this.n = grid[0].length;//获取边界
        int result = Integer.MIN_VALUE;//保存最终结果
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(grid[i][j] == 1){
                    int size = bfs(i, j);
                    result = Math.max(size, result);
                }
            }
        }
        return result == Integer.MIN_VALUE ? 0 : result;
    }
    private int bfs(int x, int y){
        int area = 1;//当前坐标陆地面积
        Queue<int[]> queue = new ArrayDeque<>();//广度优先遍历
        queue.offer(new int[]{x, y});//当前坐标入队列
        grid[x][y] = 2;//将其标志为2,表示已经访问
        while(!queue.isEmpty()){//广度优先遍历
            int[] current = queue.poll();//出队列当前坐标
            for(int[] dir : directions){//4个方向各走一步
                //获取当前方向走一步后的坐标
                int nextX = current[0] + dir[0];
                int nextY = current[1] + dir[1];
                //如果下标没有越界,并且 = 1确定是陆地,就将其加入队列中
                if(nextX >= 0 && nextX < grid.length && nextY >= 0 && nextY < grid[0].length && grid[nextX][nextY] == 1){
                    area++;//走一步,面积+1
                    queue.offer(new int[]{nextX, nextY});//入队列
                    grid[nextX][nextY] = 2;//标识为2,表示已经统计
                }
            }
        }
        return area;
    }
}
  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值