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

图论系列(dfs)9.25

一、主题空间
 

场地由若干主题空间与走廊组成,场地的地图记作由一维字符串型数组 grid,字符串中仅包含 "0"~"5" 这 6 个字符。地图上每一个字符代表面积为 1 的区域,其中 "0" 表示走廊,其他字符表示主题空间。相同且连续(连续指上、下、左、右四个方向连接)的字符组成同一个主题空间。

假如整个 grid 区域的外侧均为走廊。请问,不与走廊直接相邻的主题空间的最大面积是多少?如果不存在这样的空间请返回 0

输入:grid = ["11111100000","21243101111","21224101221","11111101111"]

输出:3

解释:8 个主题空间中,有 5 个不与走廊相邻,面积分别为 3、1、1、1、2,最大面积为 3。

image.png

思路:

题目中要求不与走廊直接相邻的主题空间的最大面积。最外层和0都是走廊。

在dfs深搜的函数中:

第一种情况:如果x在第一行或者最后一行,或者y在第一列或者最后一列(这样就意味着与走廊直接相邻了),count=-999999。

第二种情况:如果arr[x][y]=0,也代表与走廊直接相邻了,count=-999999;

        if (x == 0 || x == arr.length - 1 || y == 0 || y == arr[0].length - 1)count = -999999;

第三种情况: 相邻的点满足不与走廊相连,但是arr[x][y]!=target,这样count=-999999;

        if (x != 0) {if (arr[x - 1][y] == target) {count += dfs(x - 1, y, target);} else if (arr[x - 1][y] == 0) {count = -999999;}}

判断上下左右四个分支。(四叉树) 

代码:
class Solution {int[][] arr;public int largestArea(String[] grid) {arr = new int[grid.length][grid[0].length()];// 转换为int网格for (int i = 0; i < arr.length; i++) {String str = grid[i];for (int j = 0; j < arr[0].length; j++) {arr[i][j] = str.charAt(j) - '0';}}// dfs网格int res=0;for (int i = 1; i < arr.length; i++) {for (int j = 1; j < arr[0].length; j++) {if(arr[i][j]>0&&arr[i][j]<=5){res=Math.max(res,dfs(i,j,arr[i][j]));}}}return res;}public int dfs(int x, int y, int target) {arr[x][y] = arr[x][y] * -1;int count = 1;// 先判断是否在边界if (x == 0 || x == arr.length - 1 || y == 0 || y == arr[0].length - 1)count = -999999;// 上边进行讨论if (x != 0) {if (arr[x - 1][y] == target) {count += dfs(x - 1, y, target);} else if (arr[x - 1][y] == 0) {count = -999999;}}// 下边进行讨论if (x != arr.length - 1) {if (arr[x + 1][y] == target) {count += dfs(x + 1, y, target);} else if (arr[x + 1][y] == 0) {count = -999999;}}// 左边进行讨论if (y != 0) {if (arr[x][y - 1] == target) {count += dfs(x, y - 1, target);} else if (arr[x][y - 1] == 0) {count = -999999;}}//if (y != arr[0].length-1) {if (arr[x][y + 1] == target) {count += dfs(x, y + 1, target);} else if (arr[x][y + 1] == 0) {count = -999999;}}return count;}
}

二、飞地的数量

给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。

一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

示例 1:

输入:grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
输出:3
解释:有三个 1 被 0 包围。一个 1 没有被包围,因为它在边界上
思路:

我们可以将与边界相连的陆地都标记一下,因为与边界相连的陆地连通块是可以到达的。剩下的陆地就是无法到达边界的。

那么如何标记可以到达的陆地呢?我们可以遍历第一行、最后一行、第一列、最后一列的数,如果他们的值是1,就把值修改掉,然后继续dfs搜索。

代码:
class Solution {public int numEnclaves(int[][] grid) {//对第0行和第n-1行淹没for (int i = 0; i < grid[0].length; i++) {dfs(grid, 0, i);dfs(grid,grid.length-1,i);}//对第0列和第n-1列淹没for (int i = 0; i < grid.length; i++) {dfs(grid, i, 0);dfs(grid,i,grid[0].length-1);}int count=0;for(int i=0;i<grid.length;i++){for(int j=0;j<grid[0].length;j++){if(grid[i][j]==1)count++;}}return count;}public void dfs(int[][] grid,int x,int y){if(grid[x][y]==0)return;grid[x][y]=0;if(x>0)dfs(grid,x-1,y);if(x<grid.length-1)dfs(grid,x+1,y);if(y>0)dfs(grid,x,y-1);if(y<grid[0].length-1)dfs(grid,x,y+1);}
}


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

相关文章:

  • glide ModelLoader的Key错误使用 可能造成的内存泄漏
  • linux GPIO
  • 关于Dell r730xd 老服务器的阵列卡 配置系统盘RAID 1
  • Transformer(三):论文 Attention Is All You Need
  • sql速度优化多条合并为一条语句
  • 无线局域网四种类型
  • 问题:机器字长为n位的二进制数可以用补码来表示()个不同的有符号定点整数。
  • 2.1 HuggingFists系统架构(一)
  • java-substring 使用及注意事项
  • Elasticsearch7.7.1集群不能相互发现的问题解决以及Elasticsearch7.7.1安装analysis-ik中文分词插件的应用
  • 【ARM 嵌入式 C 入门及渐进 6.1 -- GCC 内建函数详细介绍】
  • 【Java】1.初识Java
  • 护网的过程
  • 汉王友基携手龙华区青少年宫,共推数字艺术美育新发展
  • 2024年汉字小达人区级自由报名比赛正式开始,大家最关注的问题解答
  • React学习笔记(四)——React 组件生命周期
  • 多目标跟踪中的关联代价函数
  • 前端面试题(三)
  • <<编码>> 第 17 章 自动操作(3)--带控制器的自动加法器 示例电路
  • VulgarHuman新歌《一街好戏》上线 嗨爆青岛里院喜剧节
  • EfficientNet(2019):基于复合缩放的自动化架构搜索高效网络!
  • VSCode/VS2019#include头文件时找不到头文件:我的解决方法
  • 大数据平台符合信创(CDH国产化代替)详细方案(企业内部不外传方案)
  • Redisearch 入门指南构建高性能搜索应用
  • 国内可用ChatGPT-4中文镜像网站整理汇总【持续更新】
  • 第300篇文章,第365天