当前位置: 首页 > news >正文

图论系列(dfs岛屿) 9/26

一、统计封闭岛屿的数目
 

二维矩阵 grid 由 0 (土地)和 1 (水)组成。岛是由最大的4个方向连通的 0 组成的群,封闭岛是一个 完全 由1包围(左、上、右、下)的岛。

请返回 封闭岛屿 的数目。

输入:grid = [[1,1,1,1,1,1,1],[1,0,0,0,0,0,1],[1,0,1,1,1,0,1],[1,0,1,0,1,0,1],[1,0,1,1,1,0,1],[1,0,0,0,0,0,1],[1,1,1,1,1,1,1]]
输出:2
思路:

当grid[x][y]=0的时候,我们开始遍历;对每个节点进行dfs搜索

如果该节点正好是第一行第一列或者最后一行最后一列,那么直接返回false;(因为已经到达边界了,就无法被包围了)

如果该节点正好是1并且没有被访问过,返回true,周围是1,满足被包围的条件。

向四个方向递归调用dfs,只有同时满足true,才能说明是被包围的。

代码:
class Solution {boolean[][] visited;public int closedIsland(int[][] grid) {int res = 0;visited = new boolean[grid.length][grid[0].length];for (int i = 0; i < grid.length; i++) {for (int j = 0; j < grid[0].length; j++) {if (grid[i][j] == 0 && !visited[i][j]) {if(dfs(grid,i,j))res++;}}}return res;}public boolean dfs(int[][] grid, int x, int y) {if (x < 0 || x > grid.length - 1 || y < 0 || y > grid[0].length - 1)return false;if (grid[x][y] == 1||visited[x][y])return true;visited[x][y] = true;boolean up = dfs(grid, x - 1, y);boolean down = dfs(grid, x + 1, y);boolean left = dfs(grid, x, y - 1);boolean right = dfs(grid, x, y + 1);return up && down && left && right;}
}

二、被围绕的区域(和飞地的数量类似)

题意:

给定一个m*n的矩阵,由'X'、'O'组成。如果O的四周被X包围,那么O就要改成X;

思路:

1.出现在矩阵边缘的O定不会被包围,首先寻找未被包围的‘O’,通过dfs边缘的O,寻找连通子块。

        for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if ((i == 0 || i == board.length - 1 || j == 0 || j == board[0].length - 1) && board[i][j] == 'O') {dfs(board, i, j);}}}

2.然后剩下的O就是被包围的,将他们标记成X;最后将连通子块标记成O

        for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == 'O')board[i][j] = 'X';}}for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == 'A')board[i][j] = 'O';}}}
代码:
class Solution {boolean[][] visited;public void solve(char[][] board) {visited = new boolean[board.length][board[0].length];for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if ((i == 0 || i == board.length - 1 || j == 0 || j == board[0].length - 1) && board[i][j] == 'O') {dfs(board, i, j);}}}for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == 'O')board[i][j] = 'X';}}for (int i = 0; i < board.length; i++) {for (int j = 0; j < board[0].length; j++) {if (board[i][j] == 'A')board[i][j] = 'O';}}}public void dfs(char[][] board, int x, int y) {if (x < 0 || x > board.length - 1 || y < 0 || y > board[0].length - 1 || board[x][y] != 'O')return;board[x][y] = 'A';dfs(board, x - 1, y);dfs(board, x + 1, y);dfs(board, x, y - 1);dfs(board, x, y + 1);}
}

三、统计子岛屿

给定两个岛屿,看岛屿b中的岛屿是不是岛屿a中的子岛屿。

思路1(叠加法):

因为1是陆地,所以将两个岛屿中的1相加起来,如果为2,这就是他们重叠的陆地。

如果值为2的岛屿中含有值为1的陆地,那么他就不是子岛屿;

如果都是2,说明是子岛屿。

1.叠加两个岛屿的陆地

        for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if (grid2[i][j] == 1)grid2[i][j] += grid1[i][j];}}

2.然后在叠加后中寻找值都为2的岛屿

    public boolean dfs(int[][] grid, int x, int y) {if (x < 0 || x > grid.length - 1 || y < 0 || y > grid[0].length - 1||visited[x][y])return true;if (grid[x][y] !=2)return grid[x][y]==0;visited[x][y] = true;boolean up = dfs(grid, x - 1, y);boolean down = dfs(grid, x + 1, y);boolean left = dfs(grid, x, y - 1);boolean right = dfs(grid, x, y + 1);return up&&down&&left&&right;}

代码:
class Solution {boolean[][] visited;public int countSubIslands(int[][] grid1, int[][] grid2) {visited = new boolean[grid1.length][grid1[0].length];for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if (grid2[i][j] == 1)grid2[i][j] += grid1[i][j];}}int res = 0;for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if (grid2[i][j] == 2 && !visited[i][j]) {if(dfs(grid2,i,j))res++;}}}return res;}public boolean dfs(int[][] grid, int x, int y) {if (x < 0 || x > grid.length - 1 || y < 0 || y > grid[0].length - 1||visited[x][y])return true;if (grid[x][y] !=2)return grid[x][y]==0;visited[x][y] = true;boolean up = dfs(grid, x - 1, y);boolean down = dfs(grid, x + 1, y);boolean left = dfs(grid, x, y - 1);boolean right = dfs(grid, x, y + 1);return up&&down&&left&&right;}
}
思路2(淹没法):

在相同的位置处,如果矩阵2中是陆地,矩阵1中是海洋。那么这一定不是子岛屿,直接将该陆地的连通子块都淹没掉。

淹没完不是子岛屿的岛屿,剩下的就是子岛屿的岛屿。再次寻找即可

代码:
class Solution {boolean[][] visited;public int countSubIslands(int[][] grid1, int[][] grid2) {visited = new boolean[grid1.length][grid1[0].length];for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if(grid2[i][j]==1&&grid1[i][j]==0){dfs(grid2,i,j);}}}int res = 0;for (int i = 0; i < grid2.length; i++) {for (int j = 0; j < grid2[0].length; j++) {if (grid2[i][j] == 1 && !visited[i][j]) {dfs(grid2,i,j);res++;}}}return res;}public void dfs(int[][] grid, int x, int y) {if(x<0||y<0||x>grid.length-1||y>grid[0].length-1||visited[x][y]){return ;}if(grid[x][y]==0)return;visited[x][y]=true;grid[x][y]=0;dfs(grid,x-1,y);dfs(grid,x+1,y);dfs(grid,x,y+1);dfs(grid,x,y-1);}
}


http://www.mrgr.cn/news/36693.html

相关文章:

  • 【含文档】基于Springboot+Vue的高校教务管理系统(含源码+数据库+lw)
  • 在Vue.js中,你可以使用Element UI的el-input组件结合计算属性来实现模糊查询
  • Linux这几个冷门的命令,简直不要太好用!
  • 如何在网站建设中不被外包建站公司忽悠?
  • Android常用C++特性之std::equal
  • 阿里电商再出海,蒋凡“翻身”的关键一役?
  • 免费的MBTI职业测试工具小程序
  • 自己开发一个网站系列之-网页开发初识
  • 如何利用供应链系统实现电商的高效运营
  • 博睿数据受邀亮相NebulaGraph Meetup北京站
  • 四川财谷通信息技术有限公司抖音小店强势引领电商
  • 18.1k star,cat链路监控系统,部分场景很强
  • 【libp2p——NAT】
  • Postmask eco flow – pr工具相关操作(innovus)
  • 【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU)详细理解并附实现代码。
  • 万能分销商城源码系统 源码开源可二开 带完整的安装代码包以及搭建部署教程
  • web前端(本地存储问题超过5MB不继续保存解决办法)
  • Spring异常处理-@ExceptionHandler-@ControllerAdvice-全局异常处理
  • AI应用开发中智能体编排应用是什么?
  • AI绘画美女指令大全,5个技巧让你的画作惊艳四座,美得令人窒息