文章目录

  • 岛屿问题
    • 如何在网格上做DFS(通用解)
    • 463.岛屿的周长
      • 题目
      • 题解 -通用模板
      • 题解2
    • 200.岛屿数量
      • 题目
    • 题解
    • 695.岛屿的最大面积
      • 题目
      • 题解
    • 827.最大人工岛
      • 题目
      • 题解

岛屿问题

  • 463.岛屿的周长
  • 200.岛屿数量
  • 695.岛屿的最大面积
  • 827.最大人工岛

如何在网格上做DFS(通用解)

网格问题是这样一类搜索问题:m×n 个小方格,组成一个网格,每个小方格与其上下左右四个方格认为是相邻的,要在这样的网格上进行某种搜索。

可以带入二叉树上的DFS遍历方法,分析网格上的DFS

递归的参数和终止条件

//二叉树有两个方向
function traverse(root:TreeNode){//判断base caseif(root==null)return;//二叉树只有两个相邻节点可选,左子节点,右子节点traverse(root.left);traverse(root.right);
}
//网格有四个方向
function dfs(grid:number[][],x:number,y:number):number{//x为row哪一行,y为col哪一列//base case 超出网格范围if(x<0 || y<0 || x>=grid.length || y>=grid[0].length) return;//递归的方向dfs(grid, x - 1, y); // 上边相邻dfs(grid, x + 1, y); // 下边相邻dfs(grid, x , y-1); // 左边相邻dfs(grid, x , y+1); // 右边相邻
}

如何防止重复遍历?
网格和二叉树的DFS最大的不同是遍历中可能遇到遍历过的结点,所以需要对已经遍历过的节点做标记。每走过一个陆地格子,就把格子的值改为 2,这样当我们遇到 2 的时候,就知道这是遍历过的格子了。
每个格子可能右三个取值

  • 0海洋格子
  • 1陆地格子(没有遍历过)
  • 2陆地格子(已经遍历过)
function dfs(grid:number[][],x:number,y:number):number{//x为row哪一行,y为col哪一列//base case 超出网格范围if(x<0 || y<0 || x>=grid.length || y>=grid[0].length) return;if() //可以根据条件增加一些判断,比如已经遍历过就return,或者不是陆地就return等grid[r][c] = 2 ; //将格子标记为已经遍历过了//递归的方向dfs(grid, x - 1, y); // 上边相邻dfs(grid, x + 1, y); // 下边相邻dfs(grid, x , y-1); // 左边相邻dfs(grid, x , y+1); // 右边相邻
}

463.岛屿的周长

题目

给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。

网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。

岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

示例 1:

输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
输出:16
解释:它的周长是上面图片中的 16 个黄色的边

示例 2:

输入:grid = [[1]]
输出:4

示例 3:

输入:grid = [[1,0]]
输出:4

提示:

  • row == grid.length
  • col == grid[i].length
  • 1 <= row, col <= 100
  • grid[i][j] 为 0 或 1

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/island-perimeter
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解 -通用模板

岛屿的周长就是计算岛屿的全部边缘,如从1的位置开始,如果走到了边界或者0就+1。如果走到了岛屿就继续往下走。

function islandPerimeter(grid: number[][]): number {for(let i=0;i<grid.length;i++){for(let j=0;j<grid[0].length;j++){if(grid[i][j]==1){ //只有一个岛屿return dfs(grid,i,j);}}}return 0;
};
function dfs(grid:number[][],x:number,y:number):number{if(x<0||y<0||x>=grid.length||y>=grid[0].length)return 1; //超出边界+1if(grid[x][y]==0)return 1; //从1->0,边界加1if(grid[x][y]==2)return 0; //说明已经走过了不用再走了//说明到达新陆地grid[x][y] = 2 ;return dfs(grid,x+1,y)+dfs(grid,x-1,y)+dfs(grid,x,y-1)+dfs(grid,x,y+1);
}

题解2

这道题还有更简单的解法,总周长 = 4 * 土地个数 - 2 * 接壤边的条数
遍历矩阵,遍历到土地,就 land++,如果它的右/下边也是土地,则 border++,遍历结束后代入公式。

function islandPerimeter(grid: number[][]): number {let land = 0; // 土地个数let border = 0; // 接壤边界的条数for (let i = 0; i < grid.length; i++) {for (let j = 0; j < grid[0].length; j++) {if (grid[i][j] == 1) {land++;if (i < grid.length - 1 && grid[i + 1][j] == 1) {border++;}if (j < grid[0].length - 1 && grid[i][j + 1] == 1) {border++;}}}}return 4 * land - 2 * border;
};

200.岛屿数量

题目

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:grid = [["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]
]
输出:1

示例 2:

输入:grid = [["1","1","0","0","0"],["1","1","0","0","0"],["0","0","1","0","0"],["0","0","0","1","1"]
]
输出:3

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 ‘0’ 或 ‘1’

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-islands
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

先从1开始,遍历图,走过的地方标记为2,遍历遇见0和2就返回。一个流程完说明岛屿数量+1。

function numIslands(grid: string[][]): number {let count = 0;for(let i=0;i<grid.length;i++){for(let j=0;j<grid[0].length;j++){if(grid[i][j]=='1'){ //开始遍历陆地dfs(grid,i,j);count++;}}}return count;
};function dfs(grid:string[][],x:number,y:number):void{if(x<0||y<0||x>=grid.length||y>=grid[0].length)return; //遇见边界了if(grid[x][y]!='1')return; //遇见水了//说明当前是陆地grid[x][y]='2';//修改已经走过的陆地dfs(grid,x-1,y);dfs(grid,x+1,y);dfs(grid,x,y-1);dfs(grid,x,y+1);
}

695.岛屿的最大面积

题目

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

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

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

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

示例 1:

输入:grid = [[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:

输入:grid = [[0,0,0,0,0,0,0,0]]
输出:0

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j] 为 0 或 1

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/max-area-of-island
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

和200.岛屿数量非常像,不过这里找到入口开始走岛屿时需要记录岛屿的数量。并且需要维护一个最大值的,每次一个岛屿遍历完后就进行比较。

function maxAreaOfIsland(grid: number[][]): number {let max =0;for(let i=0;i<grid.length;i++){for(let j=0;j<grid[0].length;j++){if(grid[i][j]==1){max = Math.max(max,dfs(grid,i,j)); }}}return max;
};
function dfs(grid:number[][],x:number,y:number):number{if(x<0 ||y<0||x>=grid.length||y>=grid[0].length)return 0; //出界了if(grid[x][y]!=1)return 0 ; //已经走过了或者水grid[x][y] = 2;return dfs(grid,x-1,y) + dfs(grid,x+1,y) + dfs(grid,x,y-1) + dfs(grid,x,y+1)+1;
}

827.最大人工岛

题目

给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。

返回执行此操作后,grid 中最大的岛屿面积是多少?

岛屿 由一组上、下、左、右四个方向相连的 1 形成。

示例 1:

输入: grid = [[1, 0], [0, 1]]
输出: 3
解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。

示例 2:

输入: grid = [[1, 1], [1, 0]]
输出: 4
解释: 将一格0变成1,岛屿的面积扩大为 4。

示例 3:

输入: grid = [[1, 1], [1, 1]]
输出: 4
解释: 没有0可以让我们变成1,面积依然为 4。

提示:

  • n == grid.length
  • n == grid[i].length
  • 1 <= n <= 500
  • grid[i][j] 为 0 或 1

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/making-a-large-island
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

暴力解法:遍历地图先尝试将每一个0都变成1后计算面积。先把一个0变为1,计算最大面积,然后将1变回0然后循环。
这样时间复杂度很高,每次变一个1都要重新计算最大岛屿面积。所以可以第一次先遍历依次地图,得出各个岛屿的面积(套用695题),并用map做记录,key为岛屿编号,value为岛屿面积。第二次从0开始遍历,将0变为1后,并统计周围岛屿的面积,将将其相邻加在一起。

function largestIsland(grid: number[][]): number {let n = grid.length;let m = grid[0].length;let index =2;let max = 0;let map = new Map<number,number>();for(let i=0;i<n;i++){for(let j=0;j<m;j++){if(grid[i][j]==1){let area = dfs(grid,i,j,index);map.set(index,area);index++;max = Math.max(max,area);}}}if(max==0)return 1;//将0变为1,找这个0周围的1for(let i=0;i<n;i++){for(let j=0;j<m;j++){if(grid[i][j]==0){let neighbour = findNeighbour(grid,i,j);if(neighbour.size<0)continue; //当前周围都是0,开始找下一个let total = 1 ;for(let key of neighbour){total += map.get(key)}max = Math.max(max,total);}}}return max;
};
//找当前海洋格子的相邻岛屿
function findNeighbour(grid:number[][],x:number,y:number):Set<number>{let set = new Set<number>()if(inArea(grid,x-1,y) && grid[x-1][y]!=0)set.add(grid[x-1][y]);if(inArea(grid,x+1,y) && grid[x+1][y]!=0)set.add(grid[x+1][y]);if(inArea(grid,x,y-1) && grid[x][y-1]!=0)set.add(grid[x][y-1]);if(inArea(grid,x,y+1) && grid[x][y+1]!=0)set.add(grid[x][y+1]);return set;
}
//index为每个岛屿的编号,计算每个岛屿的面积
function dfs(grid:number[][],x:number,y:number,index:number):number{if(!inArea(grid,x,y))return 0; //出界了if(grid[x][y]!=1)return 0 ; grid[x][y] = index;return dfs(grid,x-1,y,index) + dfs(grid,x+1,y,index) + dfs(grid,x,y-1,index) + dfs(grid,x,y+1,index)+1;
}
function inArea(grid:number[][],x:number,y:number):boolean{return x>=0 && x<grid.length && y>=0 && y<grid[0].length;
}

岛屿问题 通用解-463.岛屿周长-200.岛屿数量-695.岛屿的最大面积-827.最大人工岛相关推荐

  1. 200. Number of Islands**(岛屿数量)

    200. Number of Islands**(岛屿数量) https://leetcode.com/problems/number-of-islands/ 题目描述 Given an m x n ...

  2. 岛屿类-网格类问题-DFS | 力扣695. 岛屿的最大面积

    思路参考上文: 岛屿类-网格类问题-DFS | 力扣200. 岛屿数量 本文讲解695. 岛屿的最大面积问题,属于常见的岛屿类-网格类问题 本题使用DFS的思想 题目 给定一个包含了一些 0 和 1 ...

  3. LeetCode 695. 岛屿的最大面积【c++/java详细题解】

    目录 1.题目 2.思路 3.c++代码 4.java代码 1.题目 给定一个包含了一些 0 和 1 的非空二维数组 grid . 一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相 ...

  4. 力扣(Leetcode)695. 岛屿的最大面积(Java)带注释

    leetcode刷题695. 岛屿的最大面积 1.题目描述 2.解法 1.DFS(深度优先搜索) 2.DFS + 栈 1.题目描述 给你一个大小为 m x n 的二进制矩阵 grid . 岛屿 是由一 ...

  5. 每日一道leetcode(python)695. 岛屿的最大面积

    每日一道leetcode(python)695. 岛屿的最大面积 2021-08-21 给定一个包含了一些 0 和 1 的非空二维数组 grid .一个 岛屿 是由一些相邻的 1 (代表土地) 构成的 ...

  6. LeetCode 695.岛屿的最大面积

    LeetCode 695.岛屿的最大面积 给你一个大小为 m x n 的二进制矩阵 grid . 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的 ...

  7. QuickBMS通用解包器使用指南

    从本质上来说,QuickBMS只是一个通用解包器引擎,由Luigi Auriemma开发并维护,虽然QuickBMS简单而高效,技术组也经常使用QuickBMS来解包游戏的资源文件,但任何技术都存在一 ...

  8. c#求三角形面积周长公式_此题要求三角形的面积,但是无法用公式求出,而是通过方程解决...

    今天,数学世界给大家分享一道初中数学几何题,这道题的难度并不大,解决此题的关键是要理解同高不同底的两个三角形的面积比等于它们的底长之比,并要灵活运用三角形的面积公式,以及解方程组的知识.下面,我们就一 ...

  9. 695.岛屿的最大面积

    给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被水包围着. 找到给定的二维数组中 ...

最新文章

  1. 线段树 ---- Codeforces 737 Div2 D. Ezzat and Grid 维护dp
  2. [转]linux解压 tar命令
  3. 手机客户端连接linux
  4. 用MFC显示一张图片
  5. 字符指针(子串个数统计)
  6. 关于 OData 协议的数据类型 - SAP gateway 框架是如何解析数据类型的?
  7. etag java_你知道HTTP协议的ETag是干什么的吗?
  8. 连微信红包都在催我们长大:90后首次成为红包主力军
  9. 自学前端到底要学什么?五年老前端现身说法
  10. Topological Sorting(拓扑排序)
  11. 【安装库】matlab2020b安装及百度网盘提速
  12. eclipse汉化 eclipse汉化版退回英文版详细介绍
  13. AI 技术本身的一些优势,比如它能够从大量数据里去总结背后的规律
  14. 【计算机三级网络】考前看一看,必过60分
  15. caffe 训练笔记总结
  16. 安卓4.4刷linux系统下载,在Linux上安装Android 4.4 KitKat
  17. 解决pycharm导入自己写的模块飘红问题
  18. yolov5-6.0训练自己的模型
  19. 计算机应用软件开机自动启动设置,Win10系统添加/设置软件开机自动启动的方法...
  20. spring boot 启动报错Log4j2 could not find a logging implementation 解决

热门文章

  1. 我的typescript学习心得
  2. 华为系统鸿蒙命名的哲学含义,鸿蒙什么意思?华为自研操作系统为何叫鸿蒙?
  3. 多重纹理——像素着色器
  4. 如何简单快速的制作简历?
  5. 安卓UI自动化工具4399AT环境搭建
  6. 渲染类博客和游戏相关工作室论文发布地址大集合
  7. 如何为你的 Windows 应用程序关联一种或多种文件类型
  8. 企业责任彰显品牌价值,EBC金融集团助力投资者财富增值
  9. 2021年vmware安装archlinux
  10. Springboot毕设项目爱团购系统设计与实现kh533(java+VUE+Mybatis+Maven+Mysql)