DFS专题:力扣岛屿问题(持续更新)

    DFS专题:力扣岛屿问题

开篇

每次做到DFS相关的题目都是直接跳过。蓝桥杯过后痛定思痛,好好学习一下DFS和BFS。先从DFS开始吧。
参考题解:nettee:岛屿类问题的通用解法、DFS 遍历框架

一、岛屿数量

题目链接: 200.岛屿数量

题目描述

在这里插入图片描述

代码思路

使用for对每一个网格点进行判断,如果遇到未搜索过的’1’,则使岛屿数加一,并利用dfs将与其相连的‘1’都进行标记,确保每次搜索到1都是一个新的岛屿。

代码纯享版

class Solution {public int numIslands(char[][] grid) {int len = grid.length; int wide = grid[0].length; int sum = 0;for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){if(grid[i][j] == '1'){sum++;dfs(grid, i, j);}}}return sum;}void dfs(char[][] grid, int i, int j){int len = grid.length;int wide = grid[0].length;if(i < 0 || i >= len || j < 0 || j >= wide || grid[i][j] != '1'){return;}grid[i][j] = '2'; dfs(grid, i - 1, j);dfs(grid, i + 1, j);dfs(grid, i, j - 1);dfs(grid, i, j + 1);}
}

代码逐行解析版

class Solution {public int numIslands(char[][] grid) {int len = grid.length; //岛屿长度int wide = grid[0].length; //岛屿宽度int sum = 0; //岛屿总数//遍历岛屿每一个位置for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){ if(grid[i][j] == '1'){ //如果为陆地sum++; //岛屿总数加一dfs(grid, i, j); //dfs}}}return sum;}//深度搜索所有连接在一起的'1',将其变为'2'//grid[i][j] == '0' 水//grid[i][j] == '1' 未搜索的陆地//grid[i][j] == '2' 已搜索的陆地void dfs(char[][] grid, int i, int j){int len = grid.length;int wide = grid[0].length;//排除2种情况//1.超出网格范围的搜索//2.不是未搜索的陆地if(i < 0 || i >= len || j < 0 || j >= wide || grid[i][j] != '1'){ return;}grid[i][j] = '2'; //将grid[i][j] == '1'的情况标记为'2'//上下左右四个方位的搜索dfs(grid, i - 1, j);dfs(grid, i + 1, j);dfs(grid, i, j - 1);dfs(grid, i, j + 1);}
}

二、岛屿的周长

题目链接: 463.岛屿的周长

题目描述

在这里插入图片描述

代码思路

利用for循环遍历到一块陆地后,对这块陆地进行dfs搜索,遇到海洋或超出区域的部分,则周长加一;遇到未搜索过的陆地,则标记为搜索过;遇到搜索过的陆地,直接返回。

代码纯享版

class Solution {public int area = 0;public int islandPerimeter(int[][] grid) {int len = grid.length;int wide = grid[0].length;int i = 0, j = 0;int judge = 1;for(i = 0; i < len; i++){for(j = 0; j < wide; j++){if(grid[i][j] == 1){dfs(grid, i , j);return area;}}}return 0;}void dfs(int[][] grid, int i, int j){int len = grid.length;int wide = grid[0].length;if(i < 0 || i >= len || j < 0 || j >= wide || grid[i][j] == 0){area++;return;}if(grid[i][j] == 2){return;}grid[i][j] = 2;dfs(grid, i - 1, j);dfs(grid, i + 1, j);dfs(grid, i, j + 1);dfs(grid, i, j - 1);}
}

代码逐行解析版

class Solution {public int area = 0; //设周长为公共变量public int islandPerimeter(int[][] grid) {int len = grid.length; int wide = grid[0].length;for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){if(grid[i][j] == 1){ //碰到陆地,进行dfsdfs(grid, i , j); return area; //只有一块岛屿,所以搜索一次后即可返回周长}}}return 0; //没找到岛屿,返回0}void dfs(int[][] grid, int i, int j){int len = grid.length;int wide = grid[0].length;//由题目图可知,搜索到超出区域范围或海洋位置的,周长加一if(i < 0 || i >= len || j < 0 || j >= wide || grid[i][j] == 0){ area++;return;}if(grid[i][j] == 2){ //已搜索过的直接返回return;}grid[i][j] = 2; //把未搜索过的陆地标记为2:已搜索过的陆地//对上下左右进行搜索dfs(grid, i - 1, j);dfs(grid, i + 1, j);dfs(grid, i, j + 1);dfs(grid, i, j - 1);}
}

大佬相似题解

主要区别是没有设置周长变量为公共变量,而是在递归中用return来返回计算结果,感觉更高级

public int islandPerimeter(int[][] grid) {for (int r = 0; r < grid.length; r++) {for (int c = 0; c < grid[0].length; c++) {if (grid[r][c] == 1) {// 题目限制只有一个岛屿,计算一个即可return dfs(grid, r, c);}}}return 0;
}int dfs(int[][] grid, int r, int c) {// 函数因为「坐标 (r, c) 超出网格范围」返回,对应一条黄色的边if (!inArea(grid, r, c)) {return 1;}// 函数因为「当前格子是海洋格子」返回,对应一条蓝色的边if (grid[r][c] == 0) {return 1;}// 函数因为「当前格子是已遍历的陆地格子」返回,和周长没关系if (grid[r][c] != 1) {return 0;}grid[r][c] = 2;return dfs(grid, r - 1, c)+ dfs(grid, r + 1, c)+ dfs(grid, r, c - 1)+ dfs(grid, r, c + 1);
}// 判断坐标 (r, c) 是否在网格中
boolean inArea(int[][] grid, int r, int c) {return 0 <= r && r < grid.length && 0 <= c && c < grid[0].length;
}

三、岛屿的最大面积

题目链接: 695.岛屿的最大面积

题目描述

在这里插入图片描述

代码思路

利用for循环遍历到一块陆地后,对这块陆地进行dfs搜索,遇到海洋或超出区域的部分,则周长加一;遇到未搜索过的陆地,则标记为搜索过;遇到搜索过的陆地,直接返回。

代码纯享版

class Solution {public int area = 0;public int maxAreaOfIsland(int[][] grid) {int len = grid.length;int wide = grid[0].length;int max = 0; for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){if(grid[i][j] == 1){dfs(grid, i, j);max = Math.max(max, area);area = 0;}}}return max;}void dfs(int[][] grid, int i, int j){int len = grid.length;int wide = grid[0].length;if(i < 0 || i >= len || j < 0 || j >= wide || grid[i][j] != 1){return;}area++;grid[i][j] = 2;dfs(grid, i - 1, j);dfs(grid, i + 1, j);dfs(grid, i, j - 1);dfs(grid, i, j + 1);}
}

代码逐行解析版

class Solution {public int area = 0; //设岛屿的面积为公共变量public int maxAreaOfIsland(int[][] grid) {int len = grid.length;int wide = grid[0].length;int max = 0; //用来统计岛屿最大面积for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){ //遍历每一个单元格if(grid[i][j] == 1){ //遇到土地dfs(grid, i, j); //进行dfsmax = Math.max(max, area); //获取岛屿面积最大值area = 0; //将area重新设为0,方便下一块岛屿面积的计算}}}return max; //返回岛屿面积最大值}void dfs(int[][] grid, int i, int j){int len = grid.length;int wide = grid[0].length;//遇到超出的区域或水,直接返回if(i < 0 || i >= len || j < 0 || j >= wide || grid[i][j] != 1){return;}area++; //面积加一grid[i][j] = 2; //标记为搜索过//对上下左右区域进行搜索dfs(grid, i - 1, j);dfs(grid, i + 1, j);dfs(grid, i, j - 1);dfs(grid, i, j + 1);}
}

大佬相似题解

主要区别是没有设置周长变量为公共变量,而是在递归中用return来返回计算面积结果

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 = area(grid, r, c);res = Math.max(res, a);}}}return res;
}int area(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 + area(grid, r - 1, c)+ area(grid, r + 1, c)+ area(grid, r, c - 1)+ area(grid, r, c + 1);
}boolean inArea(int[][] grid, int r, int c) {return 0 <= r && r < grid.length && 0 <= c && c < grid[0].length;
}

四、最大人工岛

题目链接: 827.最大人工岛

题目描述

在这里插入图片描述

代码思路

这道题作为困难题,比前面三道复杂一点,要进行两次搜索。第一次是利用dfs,统计每一块岛屿的面积。第二次是寻找为0的节点,计算其四个方位岛屿的面积。

代码纯享版

class Solution {public static int area = 0; //面积public static Map<Integer, Integer> map = new HashMap(); //记录每块岛屿记号及对应面积public static int sign = 2; //从2开始标记public int largestIsland(int[][] grid) {int len = grid.length;int wide = grid[0].length;int max = 0;for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){if(grid[i][j] == 1){dfs(grid, i, j);map.put(sign, area);sign++;area = 0;}}}for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){if(grid[i][j] == 0){Set<Integer> set = new HashSet();if(i + 1 < len){area += map.getOrDefault(grid[i + 1][j], 0);set.add(grid[i + 1][j]);    }if(i - 1 >= 0 && !set.contains(grid[i - 1][j])){area += map.getOrDefault(grid[i - 1][j], 0);set.add(grid[i - 1][j]);}if(j + 1 < wide && !set.contains(grid[i][j + 1])){area += map.getOrDefault(grid[i][j + 1], 0);set.add(grid[i][j + 1]);}if(j - 1 >= 0 && !set.contains(grid[i][j - 1])){area += map.getOrDefault(grid[i][j - 1], 0);set.add(grid[i][j - 1]);}max = Math.max(max, area + 1);area = 0;}}}return max == 0 ? len * wide : max;}void dfs(int[][] grid, int i, int j){int len = grid.length;int wide = grid[0].length;if(i < 0 || i >= len || j < 0 || j >= wide || grid[i][j] != 1){return;}area++;grid[i][j] = sign;dfs(grid, i + 1, j);dfs(grid, i - 1, j);dfs(grid, i, j + 1);dfs(grid, i, j - 1);}
}

代码逐行解析版

class Solution {public static int area = 0; //面积public static Map<Integer, Integer> map = new HashMap(); //记录每块岛屿记号及对应面积public static int sign = 2; //从2开始标记public int largestIsland(int[][] grid) {int len = grid.length;int wide = grid[0].length;int max = 0; //记录面积最大值//第一步:利用dfs统计每一块岛屿的面积for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){ //遍历每一个点if(grid[i][j] == 1){ //遇到岛屿点dfs(grid, i, j); //通过dfs计算岛屿面积map.put(sign, area); //用map来标记岛屿序号并记录对应面积sign++;area = 0; //将面积变成0,方便下一个岛屿面积的统计}}}//第二步:找到每一个为0的点,计算其上下左右四个方位的岛屿面积和for(int i = 0; i < len; i++){for(int j = 0; j < wide; j++){if(grid[i][j] == 0){ //遇到为0的点Set<Integer> set = new HashSet(); //利用集合防止重复计算同一片岛屿//对四个方向的岛屿面积进行相加if(i + 1 < len){area += map.getOrDefault(grid[i + 1][j], 0);set.add(grid[i + 1][j]);    }if(i - 1 >= 0 && !set.contains(grid[i - 1][j])){area += map.getOrDefault(grid[i - 1][j], 0);set.add(grid[i - 1][j]);}if(j + 1 < wide && !set.contains(grid[i][j + 1])){area += map.getOrDefault(grid[i][j + 1], 0);set.add(grid[i][j + 1]);}if(j - 1 >= 0 && !set.contains(grid[i][j - 1])){area += map.getOrDefault(grid[i][j - 1], 0);set.add(grid[i][j - 1]);}max = Math.max(max, area + 1); //取最大值,area+1的加一是将grid[i][j]=0变成1area = 0;}}}//如果找不到为0的单元格,证明该矩阵全部都是1,直接返回矩阵面积,否则返回maxreturn max == 0 ? len * wide : max; }void dfs(int[][] grid, int i, int j){int len = grid.length;int wide = grid[0].length;//排除超出区域的情况和已统计过的情况if(i < 0 || i >= len || j < 0 || j >= wide || grid[i][j] != 1){ return;}area++; //面积加一grid[i][j] = sign; //标记岛屿记号,也使其被标记为统计过//上下左右四个方位进行搜索dfs(grid, i + 1, j);dfs(grid, i - 1, j);dfs(grid, i, j + 1);dfs(grid, i, j - 1);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/819654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3学习05 一些API

Vue3-API 其它 API【shallowRef 与 shallowReactive 】shallowRefshallowReactive总结 【readonly 与 shallowReadonly】readonlyshallowReadonly 【toRaw 与 markRaw】toRawmarkRaw 【customRef】 Vue3新组件【Teleport】【Suspense】【全局API转移到应用对象】【其他】 其它 …

BackTrader 中文文档(一)

原文&#xff1a;www.backtrader.com/ 主页 欢迎来到 backtrader&#xff01; 原文&#xff1a;www.backtrader.com/ 一个功能丰富的 Python 框架&#xff0c;用于回测和交易 backtrader允许您专注于编写可重复使用的交易策略、指标和分析器&#xff0c;而不必花时间构建基础…

Android T多屏多显——应用双屏间拖拽移动功能(更新中)

功能以及显示效果简介 需求&#xff1a;在双屏显示中&#xff0c;把启动的应用从其中一个屏幕中移动到另一个屏幕中。 操作&#xff1a;通过双指按压应用使其移动&#xff0c;如果移动的距离过小&#xff0c;我们就不移动到另一屏幕&#xff0c;否则移动到另一屏。 功能分析…

振弦式渗压计的安装与防护:在水工建筑物中的关键应用

振弦式渗压计&#xff0c;作为一种高效的孔隙水压力或液体液位测量工具&#xff0c;广泛应用于水工建筑物、基岩内、测压管、钻孔、堤坝、管道和压力容器内。其安装和防护工作至关重要&#xff0c;直接关系到测量数据的准确性和仪器的使用寿命。本文将重点探讨振弦式渗压计在填…

RabbitMQ实战教程(1)

RabbitMQ 一、RabbitMQ介绍 1.1 现存问题 服务调用&#xff1a;两个服务调用时&#xff0c;我们可以通过传统的HTTP方式&#xff0c;让服务A直接去调用服务B的接口&#xff0c;但是这种方式是同步的方式&#xff0c;虽然可以采用SpringBoot提供的Async注解实现异步调用&…

Ue不消耗輸入

1、介紹 我們都知道ue裏面使用輸入時&#xff0c;都是在PlayerController裏面進行獲取&#xff0c; 使用官方的操作映射&#xff0c;軸映射&#xff0c;以及目前最新的增强型輸入 但是我們發現了一個問題 那就是輸入會被消耗 就是儅我鼠標按在一個按鈕上時 你另一個地方接受…

Elastic安装后 postman对elasticsearch进行测试

一、创建索引和mapping //id 字段自增id //good_sn 商品SKU //good_name 商品名称 //good_introduction 商品简介 //good_descript 商品详情 PUT http://IP:9200/shop { "mappings":{ "good":{ "properties":{ …

LabVIEW光学探测器板级检测系统

LabVIEW光学探测器板级检测系统 特种车辆乘员舱的灭火抑爆系统广泛采用光学探测技术来探测火情。光学探测器作为系统的关键部件&#xff0c;其探测灵敏度、响应速度和准确性直接关系到整个系统的运行效率和安全性。然而&#xff0c;光学探测器在长期使用过程中可能会因为灰尘污…

牛客Linux高并发服务器开发学习第一天

Linux开发环境搭建 安装Xshell 7远程连接虚拟机的Ubuntu 安装Xftp 7可以传输文件(暂时还没使用) 安装VMware Tools可以直接从Windows系统向虚拟机Linux系统拖拽文件实现文件交互。 安装CScode可以远程连接Linux系统进行代码的编写。&#xff08;Windows系统与Linxu系统公钥…

ActiveMQ 任意文件上传漏洞复现

一、使用弱口令登陆 ​ 访问 http://ip:8161/admin/ 进入admin登陆页面&#xff0c;使用弱口令登陆&#xff0c;账号密码皆为 admin&#xff0c;登陆成功后&#xff0c;headers中会出现验证信息 ​ 如&#xff1a; Authorization: Basic YWRtaW46YWRtaW4 # 二、利用PUT协议上…

STL体系结构与各容器基本介绍

STL体系结构与各容器基本介绍 STL体系结构基本容器序列式关联式&#xff08;查找更快&#xff09;其他&#xff08;不常用&#xff09;使用分配器 STL体系结构 六大模块 容器算法迭代器适配器仿函数分配器 基本容器 序列式 array c11新标准array<类型&#xff0c;大小&…

Linux-管道

目录 无名管道关闭未使用的管道文件描述符 管道对应的内存大小与shell命令进行通信&#xff08;popen&#xff09;命名管道FIFO创建FIFO文件打开FIFO文件 无名管道 管道是最早出现的进程间通信的手段。 管道的作用是在有亲缘关系的进程之间传递消息。所谓有亲缘关系&#xff…

MySQL中的SQL高级语句[二]

使用语言 MySQL 使用工具 Navicat Premium 16 代码能力快速提升小方法&#xff0c;看完代码自己敲一遍&#xff0c;十分有用 拖动表名到查询文件中就可以直接把名字拉进来以下是使用脚本方法&#xff0c;也可以直接进行修改中括号&#xff0c;就代表可写可不写 有些地方的代…

IO——标准IO

1.1概念 标准IO&#xff1a;是在C库中定义的一组专门用于输入输出的函数。 1.2特点 &#xff08;1&#xff09;通过缓冲机制减少系统调用&#xff0c;提高效率 &#xff08;2&#xff09;围绕流操作&#xff0c;用FILE*描述 &#xff08;3&#xff09;标准IO默认打开三个流&a…

PCIe错误定义与分类

前言&#xff1a; PCI总线中定义两个边带信号&#xff08;PERR#和SERR#&#xff09;来处理总线错误。其中PERR#主要对应的是普通数据奇偶校检错误&#xff08;Parity Error&#xff09;&#xff0c;而SERR#主要对应的是系统错误&#xff08;System Error&#xff09;。具体如下…

数据结构复习指导之绪论(算法的概念以及效率的度量)

文章目录 绪论&#xff1a; 2.算法和算法评价 知识总览 2.1算法的基本概念 知识点回顾与重要考点 2.2算法效率的度量 知识总览 1.时间复杂度 2.空间复杂度 知识点回顾与重要考点 归纳总结 绪论&#xff1a; 2.算法和算法评价 知识总览 2.1算法的基本概念 算法( Al…

【现代C++】模块的使用

C20引入了模块的概念&#xff0c;这是一个重要的新特性&#xff0c;旨在替代传统的预处理器和头文件机制。模块旨在提高编译速度、改善代码封装性、减少名称污染&#xff0c;并提供更好的工具支持。下面详细介绍模块的关键概念和使用方法&#xff1a; 1. 模块的基本概念 模块…

openGauss学习笔记-263 openGauss性能调优-TPCC性能调优测试指导-前置软件安装

文章目录 openGauss学习笔记-263 openGauss性能调优-TPCC性能调优测试指导-前置软件安装263.1 安装jdk263.2 安装numactl263.3 安装ant263.4 安装htop工具 openGauss学习笔记-263 openGauss性能调优-TPCC性能调优测试指导-前置软件安装 本章节主要介绍openGauss数据库内核基于…

谷歌浏览器的开发者插件vue-devtools

在这里我留下一个git地址用来下载插件包&#xff0c;首先在自己喜欢的位置创建一个新的文件夹&#xff0c;起一个自己喜欢的文件夹名字&#xff0c;下载到包后&#xff0c;然后点进文件夹里下载依赖&#xff0c;npm install,下载后如下面这个样子 git clone https://gitee.com…

【投稿优惠-EI稳定检索】2024年人工智能、自然语言处理与机器学习国际会议(ICAINLPML 2024)

2024 International Conference on Artificial Intelligence, Natural Language Processing and Machine Learning (ICAINLPML 2024) 网址&#xff1a;www.icainlpml.com 邮箱: ainlpmlsub-conf.com ●会议简介 2024年人工智能、自然语言处理与机器学习国际会议将邀请全球人…