力扣刷题---岛屿问题--c++

DFS:深度优先遍历:深度优先遍历是一种优先走到底、无路可走再回头的遍历方式

我们所熟悉的 DFS(深度优先搜索)问题通常是在树或者图结构上进行的。而我们今天要讨论的 DFS 问题,是在一种「网格」结构中进行的。岛屿问题是这类网格 DFS 问题的典型代表。网格结构遍历起来要比二叉树复杂一些,如果没有掌握一定的方法,DFS 代码容易写得冗长繁杂。

网格类问题的 DFS 遍历方法

网格问题的基本概念:
我们首先明确一下岛屿问题中的网格结构是如何定义的,以方便我们后面的讨论。

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

岛屿问题是一类典型的网格问题。每个格子中的数字可能是 0 或者 1。我们把数字为 0 的格子看成海洋格子,数字为 1 的格子看成陆地格子,这样相邻的陆地格子就连接成一个岛屿。

在这样一个设定下,就出现了各种岛屿问题的变种,包括岛屿的数量、面积、周长等。不过这些问题,基本都可以用 DFS 遍历来解决。

DFS遍历基本框架:

1.跳出条件

2.遍历方向

类比树的DFS遍历,树:跳出条件--》root==null;遍历方向---》左右孩子

void dfs(TreeNode*root) {//边界条件if (!root) {return;}// 访问两个相邻结点:左子结点、右子结点dfs(root->left);dfs(root->right);
}

由此我们可以推出网格的dfs遍历:跳出条件:数组下标越界;遍历方向:上下左右

注意当 r == grid.size()时,是越界! 

但访问过得节点肯定不能再次访问了,那如何标记呢?可以直接将值变为2(区别于0,1)

于是有了三种情况

  • 0 —— 海洋
  • 1 —— 陆地(未遍历过)
  • 2 —— 陆地(已遍历过)
void dfs(vector<vector<int>>& grid, int r, int c) {// 判断 base caseif (!inArea(grid, r, c)) {return;}// 如果这个格子不是岛屿,直接返回if (grid[r][c] != 1) {return;}grid[r][c] = 2; // 将格子标记为「已遍历过」// 访问上、下、左、右四个相邻结点dfs(grid, r - 1, c);dfs(grid, r + 1, c);dfs(grid, r, c - 1);dfs(grid, r, c + 1);
}// 判断坐标 (r, c) 是否在网格中
bool inArea(vector<vector<int>>& grid, int r, int c) {return 0 <= r && r < grid.size() && 0 <= c && c < grid[0].size();
}

说回本题:判断岛屿的个数:其实可以理解为能进行几次DFS。(进行一次深度遍历,将本块岛屿的所有小岛全部标记)

由此得到本题代码:

注意本题vetor类型为char;上面解释里面写的为int类型。

class Solution {
public:void dfs(vector<vector<char>>& grid, int r, int c) {// 判断 base caseif (!inArea(grid, r, c)) {return;}// 如果这个格子不是岛屿,直接返回if (grid[r][c] != '1') {return;}grid[r][c] = 2; // 将格子标记为「已遍历过」// 访问上、下、左、右四个相邻结点dfs(grid, r - 1, c);dfs(grid, r + 1, c);dfs(grid, r, c - 1);dfs(grid, r, c + 1);}// 判断坐标 (r, c) 是否在网格中bool inArea(vector<vector<char>>& grid, int r, int c) {return 0 <= r && r < grid.size() && 0 <= c && c < grid[0].size();}int numIslands(vector<vector<char>>& grid) {int ans = 0;for (int i = 0; i < grid.size(); i++) {for (int j = 0; j < grid[0].size(); j++) {if (grid[i][j] == '1') {//找到一块未标记的岛屿ans++;//数量+1dfs(grid, i, j);//迅速占领}}}return ans;}
};

再来一道

463. 岛屿的周长

什么情况下周长增加:1.这个边是海和岛的分界线 2.边是临界边(网格的头)

if(gird[i][j]==0) return 1;
if(!inarea[i][j]) return 1;
if(grid[i][j]==2) return 0;

所以完整代码:

class Solution {
public:int dfs(vector<vector<int>>& grid, int row, int col) {if (!inarea(grid, row, col))return 1;if (grid[row][col] == 0)return 1;if (grid[row][col] != 1)return 0;grid[row][col] = 2;return dfs(grid, row + 1, col) + dfs(grid, row - 1, col) +dfs(grid, row, col + 1) + dfs(grid, row, col - 1);}bool inarea(vector<vector<int>>& grid, int row, int col) {if (row < 0 || row >=grid.size())return false;if (col < 0 || col >=grid[0].size())return false;return true;}int islandPerimeter(vector<vector<int>>& grid) {int ans = 0;for (int i = 0; i < grid.size(); i++) {for (int j = 0; j < grid[0].size(); j++) {if (grid[i][j] == 1)ans += dfs(grid, i, j);}}return ans;}
};

再来一道: 

695. 岛屿的最大面积

题目简单清晰明了,岛屿的面积是岛上值为 1 的单元格的数目。所以只需要返回

最大的值为 1 的单元格数目之和就可以啦。

class Solution {
public:int max_ans = 0;int ans = 0;void dfs(vector<vector<int>>& grid, int row, int col) {if (!inarea(grid, row, col))return;if (grid[row][col] == 0 || grid[row][col] == 2)return;ans += 1;grid[row][col] = 2;// 访问上、下、左、右四个相邻结点dfs(grid, row - 1, col);dfs(grid, row + 1, col);dfs(grid, row, col - 1);dfs(grid, row, col + 1);}bool inarea(vector<vector<int>>& grid, int row, int col) {if (row < 0 || row >= grid.size())return false;if (col < 0 || col >= grid[0].size())return false;return true;}int maxAreaOfIsland(vector<vector<int>>& grid) {for (int i = 0; i < grid.size(); i++) {for (int j = 0; j < grid[0].size(); j++) {if (grid[i][j] == 1) {ans=0;dfs(grid, i, j);max_ans = max(ans, max_ans);}}}return max_ans;}
};

好了,以上就结束了,另外,强烈建议看看参考链接,太6了。

参考链接:. 岛屿问题- 力扣(LeetCode)

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

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

相关文章

源码部署LAMP架构

LAMP 文章目录 LAMP1. lamp简介2. web服务器工作流程2.1 cgi与fastcgi2.2 httpd与php结合的方式2.3 web工作流程 3. LAMP平台构建3.1 安装httpd3.2 安装mysql3.3 安装php3.4 验证 1. lamp简介 有了前面学习的知识的铺垫&#xff0c;今天可以来学习下第一个常用的web架构了。 …

【基于HTML5的网页设计及应用】——动态添加下拉菜单

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

什么是增强型SSL证书?购买一张需要多少钱?

增强型SSL证书是一种提供更高级别安全验证与用户信任度的网络安全工具&#xff0c;也被称为EV证书。相较于DV&#xff08;域名验证&#xff09;和OV&#xff08;组织验证&#xff09;证书&#xff0c;它通过严格的身份核实流程确保网站所有者的合法性和真实性。 首先&#xff0…

【C++】string 类---字符判断与大小写转换(超详细解析!)

目录 一、string 类的介绍 二、字符大小写转换与判断常用函数 &#x1f4a6; 字符大小写判断 ① isalpha() ② isalnum() ③ isdigit() ④ islower() ⑤ isupper() &#x1f4a6; 字符大小写转换 ① tolower() ✨方法一&#xff1a; ✨方法二&#xff1a; ② toupper() ✨方…

【MySQL】MySQL视图

文章目录 一、视图的基本使用1.创建视图2.修改了视图&#xff0c;对基表数据有影响3.修改了基表&#xff0c;对视图有影响4.删除视图 二、视图规则和限制 一、视图的基本使用 视图是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称…

【springboot】@SpringBootApplication 加载原理解析

从何处放入 AutoConfigurationImportSelector.selectImports AbstractApplicationContext.refresh AbstractApplicationContext.invokeBeanFactoryPostProcessors PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors 此处一个关键信息 只有BeanDefinition…

Html Open with Live Server 报错windows找不到文件

输入setting.json 填入你的浏览器路径 即可

【Qt】Qt代码格式化配置

这里记录一下个人使用的格式化配置: 个人使用的格式化工具Artistic Style格式化信息&#xff1a; --stylelinux #&#xff1a;Linux 风格格式和缩进 #--stylekr #indentspaces4 # 缩进采用4个空格 -A1 #使用AllMan程序风格&#xff0c;即大括号另起一行。 indent-switche…

java入门-变量与常量

java 基本语法-变量与常量 变量 变量的本质 程序中我们会经常看到类似 int x 3**;** 的表达式&#xff0c;x就是我们常说的变量&#xff0c;从计算机角度我们来看看变量x的本质是什么&#xff1f; 在程序开发中定义一个变量x, 计算机会在内存中开辟内存空间&#xff0c;计算…

测电笔与零火线

火线零线不分正负&#xff0c;因此即使接反电气仍可以使用&#xff0c;只是当开关断电的时候灯泡是有电的&#xff0c;此时比较危险容易触电。 火线和零线上的电流都是正弦波。简单的来讲&#xff0c;对于交流电路&#xff0c;电流一会从火线出发通过用电设备流向零线&#xff…

上位机图像处理和嵌入式模块部署(qmacvisual预处理实战)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面&#xff0c;我们说了图像预处理&#xff0c;但是没有给出相应的实战案例。今天还是有必要做一个说明的。预处理方法虽然相关的算法很多&#…

实现el-table合并列

效果图如下 <el-table :data"atlasDataList" style"width: 100%" :span-method"spanMethod"><el-table-column prop"stationName" label"" width"180" /><el-table-column prop"atlasNumbe…

中间件-消息队列

消息队列基础知识 什么是消息队列 本处提到的消息队列是指各个服务以及系统组件/模块之间的通信&#xff0c;属于一种中间件。参与消息传递的双方称为生产者和消费者&#xff0c;生产者负责发送消息&#xff0c;消费者负责处理消息。 消息队列作用 通过异步处理&#xff0…

你知道三拳打死镇关西的故事吗?郑屠户做了什么让鲁达竟将他置于死地?

你知道三拳打死镇关西的故事吗&#xff1f;郑屠户做了什么让鲁达竟将他置于死地&#xff1f; 《水浒传》第二集里&#xff0c;咱们看到了鲁提辖&#xff0c;也就是鲁达&#xff0c;他为啥要打郑屠户&#xff0c;也就是人们常说的镇关西。这鲁提辖可是个仗义疏财的好汉&#xf…

好委屈,东方甄选为何总是被供应商骗?

东方甄选最近很委屈。 315晚会过后&#xff0c;知名打假人王海爆料&#xff0c;称315晚会曝光的槽头肉扣肉在东方甄选和小杨哥的直播间里销售过。 东方甄选赶忙去问了问供应商情况。 供应商的回答让他感到暖心&#xff0c;表示虽然315晚会曝光了我们公司违规使用糟头肉&…

vue3项目

案例用到的知识点如下&#xff1a; ① vite 创建项目 ② 组件的封装与注册 ③ props ④ 样式绑定 ⑤ 计算属性 ⑥ 自定义事件 ⑦ 组件上的 v-model 效果如下图&#xff1b; 页面2 项目结构&#xff1a; 初始化项目 在终端运行以下的命令&#xff0c;初始化 vite 项目&#xf…

每日五道java面试题之mybatis篇(五)

目录&#xff1a; 第一题. 实体类属性名和表中字段名不⼀样 &#xff0c;怎么办?第二题. Mybatis是否可以映射Enum枚举类&#xff1f;第三题. Mybatis能执⾏⼀对⼀、⼀对多的关联查询吗&#xff1f;第四题. Mybatis是否⽀持延迟加载&#xff1f;原理&#xff1f;第五题. 如何获…

【项目实践day06】JWT令牌相关

什么是JWT 简洁的、自包含的格式&#xff0c;用于在通信双方以json数据格式安全的传输信息。 由于数字签名的存在&#xff0c;这些信息是可靠的。 jwt就是将原始的json数据格式进行了安全的封装&#xff0c;这样就可以直接基于jwt在通信双方安全的进行信息传输了。简洁&#…

CTF 题型 SSRF攻击例题总结

CTF 题型 SSRF攻击&例题总结 文章目录 CTF 题型 SSRF攻击&例题总结Server-side Request Forgery 服务端请求伪造SSRF的利用面1 任意文件读取 前提是知道要读取的文件名2 探测内网资源3 使用gopher协议扩展攻击面Gopher协议 &#xff08;注意是70端口&#xff09;python…

前端项目,个人笔记(五)【图片懒加载 + 路由配置 + 面包屑 + 路由行为修改】

目录 1、图片懒加载 步骤一&#xff1a;自定义全局指令 步骤二&#xff1a;代码中使用 ​编辑步骤三&#xff1a;效果查看 步骤四&#xff1a;代码优化 2、封装组件案例-传对象 3、路由配置——tab标签 4、根据tab标签添加面包屑 4.1、实现 4.2、bug&#xff1a;需要…