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

算法|图论 3

LeetCode 130- 被围绕的区域

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目描述:给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

解题思路(思路一是自己的思路,思路二题解思路,不过用两种遍历方式写出来)

思路一(深度优先遍历):

我的思路:是开辟一个二维数组,存储二元组,来记录那些下标,首先是一个一维数组,每次记录我们当前遍历岛屿的下标,当被环绕的时候压入到二维数组中,否则直接清空。类似将所有岛屿都淹没,然后再看哪些岛屿没被包围再还原成陆地。

  1. 首先确定递归函数的参数,返回值。覆盖那些被环绕的区域,我们直接设置两个全局变量vec(存储所有需要还原的海洋)和tmp(存储当前我们遍历的这片岛屿的下标),flag表示是否被包围,这样可以不用写太多参数传递。返回值就是void,参数需要图和一个x和y来记录当前在哪个岛屿。下次从这个岛屿开始走的。
  2. 确定终止条件,本题按我们的逻辑,先进入循环再判断是否应该终止,那么终止条件就是:当超出网格范围(这里还需要把flag 设置为false,表示没被包围) 或 该岛屿已经是海洋 就终止。
  3. 单层处理逻辑,每次将当前岛屿淹没(这里也就是设置为'X'),然后将其下标压入tmp(为什么有tmp,是因为我们不知道当前的这片岛屿马上是否要恢复,也就是变成'O'所以需要一个临时的,当我们确定要恢复的时候就将其压入到vec中)。
class Solution {
public:bool flag = true; //表示是否被环绕(只要相连的岛屿有一个在边界就不是被环绕的),被环绕就不用撤回修改vector<vector<pair<int,int>>> vec;//存所有岛屿下标,其中全都是要变回'O'的vector<pair<int,int>> tmp; //保存当前遍历这片岛屿的下标,一会可能填充。void dfs(vector<vector<char>> &grid,int x,int y){if(x < 0 || y < 0 || x >= grid.size() || y >= grid[0].size()){flag = false;//表示没有被环绕return ;}if(grid[x][y] == 'X') return;tmp.push_back({x,y});//压入当前岛屿的下标grid[x][y] = 'X';dfs(grid,x+1,y);dfs(grid,x-1,y);dfs(grid,x,y+1);dfs(grid,x,y-1);}void solve(vector<vector<char>>& grid) {int m = grid.size(),n = grid[0].size();for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(grid[i][j] == 'O'){dfs(grid,i,j);//当flag为false,也就是岛屿没有被包围,我们就将其压入vec中,最后再还原if(flag == false){vec.push_back(tmp);tmp.clear();//这里注意要把tmp清空了,方便下次使用flag = true;//flag再改为默认值}else{//这里不改flag是因为如果走这个分支,那flag一定还是默认值truetmp.clear();}}}}//将未被包围的小岛屿还原为'O'for(int i=0;i<vec.size();i++){for(int j=0;j<vec[i].size();j++){grid[vec[i][j].first][vec[i][j].second] = 'O';}}return ;}
};

思路二(广度优先遍历):

比较猛的一个思路:本题我们可以看到,只有和边界相连的O不会变,其余的都得变成X,那么我们可以将与边界相连的所有O全部变成一个特定符号如'-',这样,其中所有的'-'都是与边界相连的,马上会再变成'O'。而这个时候图中所有的'O'都是被包围的,全都变为'X'即可。

class Solution {
public:int dir[4][2] = {0,1,1,0,-1,0,0,-1};void bfs(vector<vector<char>> &grid,int x,int y){queue<pair<int,int>> que;que.push({x,y});grid[x][y] = '-';//将与边界相连的全部变为'-'//广度优先遍历while(!que.empty()){pair<int,int> cur = que.front();que.pop();for(int i=0;i<4;i++){int nextx = cur.first + dir[i][0];int nexty = cur.second + dir[i][1];if(nextx < 0 || nexty < 0 || nextx >= grid.size() || nexty >= grid[0].size() ||grid[nextx][nexty] != 'O') continue;que.push({nextx,nexty});grid[nextx][nexty] = '-';}}}void solve(vector<vector<char>>& grid) {int row = grid.size(),col = grid[0].size();for(int i=0;i<col;i++){//遍历第一行的所有列if(grid[0][i] == 'O') bfs(grid,0,i);//遍历最后一行的所有列if(grid[row-1][i] == 'O') bfs(grid,row-1,i);}for(int i=0;i<row;i++){//遍历第一列的所有行if(grid[i][0] == 'O') bfs(grid,i,0);//遍历最后一列的所有行if(grid[i][col-1] == 'O') bfs(grid,i,col-1);}//这个时候图中所有'-'都是与边界相连的,所有'O'都是被包围起来的。for(int i=0;i<row;i++){for(int j=0;j<col;j++){//这俩式子顺序反了,导致花了我半小时调试if(grid[i][j] == 'O')grid[i][j] = 'X';if(grid[i][j] == '-')grid[i][j] = 'O';}}return ;}
};

总结:

  • 深搜和广搜的问题,广搜里面写的那个思路很清奇,还是得多看题目的提示,可以减少一点时间和空间的损耗。

LeetCode 417- 太平洋大西洋水流问题

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目描述:有一个 m × n 的矩形岛屿,与 太平洋大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。

这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heights , heights[r][c] 表示坐标 (r, c) 上单元格 高于海平面的高度

岛上雨水较多,如果相邻单元格的高度 小于或等于 当前单元格的高度,雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。

返回网格坐标 result 的 2D 列表 ,其中 result[i] = [ri, ci] 表示雨水从单元格 (ri, ci) 流动 既可流向太平洋也可流向大西洋

解题思路

首先明确本题题意,意思就是雨水高的地方能往雨水低的地方流,要我们求出能流向两大洋的点坐标。

思路一(深度优先遍历):

这题总体思路就是遍历边界点(也就是能直接流进大洋的点),再逆流遍历,因为雨水往低处流,我们逆流遍历就可以找到所有大于边界的雨水高度的点,这些点就是可以直接流进大洋的点

  1. 首先确定递归函数的参数,返回值。参数我们需要设置一个isvisited来表示这个点能不能走到其中一个大洋中去。还有x,y坐标来表示当前遍历到的点的位置
  2. 确定终止条件,本题按我们的逻辑,先进入循环再判断是否应该终止,那么终止条件就是:当超出网格范围 当前遍历的是海洋 就跳过。不过这里需要注意,这道题目我们这里的逻辑是逆流而上,所以下一次要去的节点的雨水高度 小于 我们当前节点的雨水高度的时候也直接跳过。
  1. 单层处理逻辑,每次进入递归,我们就将访问设置为true,代表可以直接流进大洋。不过在处理遍历的时候有点麻烦,需要注意m和n各表示的是什么,别弄混了。
class Solution {
private:int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1}; // 保存四个方向// 从低向高遍历,注意这里visited是引用,即可以改变传入的pacific和atlantic的值void dfs(vector<vector<int>>& heights, vector<vector<bool>>& visited, int x, int y) {if (visited[x][y]) return;visited[x][y] = true;for (int i = 0; i < 4; i++) { // 向四个方向遍历int nextx = x + dir[i][0];int nexty = y + dir[i][1];// 超过边界if (nextx < 0 || nextx >= heights.size() || nexty < 0 || nexty >= heights[0].size()) continue;// 高度不合适,注意这里是从低向高判断if (heights[x][y] > heights[nextx][nexty]) continue;dfs (heights, visited, nextx, nexty);}return;}
public:vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {vector<vector<int>> result;int n = heights.size();int m = heights[0].size(); // 这里不用担心空指针,题目要求说了长宽都大于1// 记录从太平洋边出发,可以遍历的节点vector<vector<bool>> pacific = vector<vector<bool>>(n, vector<bool>(m, false));// 记录从大西洋出发,可以遍历的节点vector<vector<bool>> atlantic = vector<vector<bool>>(n, vector<bool>(m, false));// 从最上最下行的节点出发,向高处遍历for (int i = 0; i < n; i++) {dfs (heights, pacific, i, 0); // 遍历最上行,接触太平洋dfs (heights, atlantic, i, m - 1); // 遍历最下行,接触大西洋}// 从最左最右列的节点出发,向高处遍历for (int j = 0; j < m; j++) {dfs (heights, pacific, 0, j); // 遍历最左列,接触太平洋dfs (heights, atlantic, n - 1, j); // 遍历最右列,接触大西洋}for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 如果这个节点,从太平洋和大西洋出发都遍历过,就是结果if (pacific[i][j] && atlantic[i][j]) result.push_back({i, j});}}return result;}
};

总结:

  • 逆流而上的操作,主要是根据边界来想到了这个思路。

相关文章:

算法|图论 3

LeetCode 130- 被围绕的区域 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目描述&#xff1a;给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和 O &#xff0c;找到所有被 X 围绕的区域&#xff0c;并将这些区域…...

【数据结构】二叉树的层序遍历(四)

目录 一&#xff0c;层序遍历概念 二&#xff0c;层序遍历的实现 1&#xff0c;层序遍历的实现思路 2&#xff0c;创建队列 Queue.h Queue.c 3&#xff0c;创建二叉树 BTree.h BTree.c 4&#xff0c;层序遍历的实现 一&#xff0c;层序遍历概念 层序遍历&#xff1a;除了先序…...

macOS文件差异比较最佳工具:Beyond Compare 4

Beyond Compare for mac是一款Scooter Software研发的文件同步对比工具。你可以选择针对多字节的文本、文件夹、源代码&#xff0c;甚至是支持比对adobe文件、pdf文件或是整个驱动器&#xff0c;检查其文件大小、名称、日期等信息。你也可以选择使用Beyond Compare合并两个不同…...

Windows+Pycharm 如何创建虚拟环境

当我们开发一个别人的项目的时候,因为项目里有很多特有的包,比如 Pyqt5.我们不想破坏电脑上原来的包版本,这个时候,新建一个虚拟环境,专门针对这个项目就很有必要了. 简略步骤: 1.新建虚拟环境 1.打开 pycharm 终端(Terminal)安装虚拟环境工具: pip install virtualenv2.创…...

vant 按需导入 vue2

vant 按需导入 vue2 1、通过npm安装 # Vue 3 项目&#xff0c;安装最新版 Vant&#xff1a; npm i vant -S# Vue 2 项目&#xff0c;安装 Vant 2&#xff1a; npm i vantlatest-v2 -S2、自动按需引入组件 babel-plugin-import 是一款 babel 插件&#xff0c;它会在编译过程中…...

Java手写分治算法和分治算法应用拓展案例

Java手写分治算法和分治算法应用拓展案例 1. 算法思维导图 以下是用Mermanid代码表示的分治算法的实现原理&#xff1a; #mermaid-svg-nvJwIm97kPHEXQOR {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-nvJwIm97kP…...

学习 CodeWhisperer 的一些总结

目前一些常见的的 AI 工具 GitHub Copilot&#xff1a;GitHub 与 OpenAI 合作开发的一个人工智能助手。 Codeium&#xff1a;是一个免费的人工智能驱动的代码生成工具 Tabnine&#xff1a;一个自动代码生成工具&#xff0c;免费版本非常有限&#xff0c;只提供简短的代码完成…...

JavaScript 中的 `this` 指向问题与其在加密中的应用

JS中的 this 关键字是一个非常重要的概念&#xff0c;它在不同情况下会指向不同的对象或值。在本文中&#xff0c;我们将深入探讨 JavaScript 中 this 的各种情况&#xff0c;并思考如何将其应用于 JS加密中的一些有趣用途。 1. 全局上下文中的 this 在全局上下文中&#xff…...

深入理解算法的时间复杂度

文章目录 时间复杂度的定义时间复杂度的分类时间复杂度分析常见数据结构和算法的时间复杂度常见数据结构常见算法 常见排序算法说明冒泡排序(Bubble Sort)快速排序(Quick Sort)归并排序(Merge Sort)堆排序(Heap Sort) 时间复杂度的定义 时间复杂度就是一种用来描述算法在输入规…...

2023年度教育部人文社会科学研究一般项目评审结果,已公布!

【SciencePub学术】 9月15日&#xff0c;教育部社科司公示了2023年度教育部人文社会科学研究一般项目评审结果&#xff0c;共3482项。 其中&#xff0c;规划基金、青年基金、自筹经费项目共3029项通过专家评审&#xff1b;西部和边疆地区项目200项&#xff0c;新疆项目20项&a…...

十一、MySql的事务(上)

文章目录 一、引入&#xff08;一&#xff09;CURD不加控制&#xff0c;会有什么问题&#xff1f;&#xff08;二&#xff09;CURD满足什么属性&#xff0c;能解决上述问题&#xff1f; 二、什么是事务&#xff1f;三、事务的特性&#xff08;一&#xff09;原子性&#xff1a;…...

时间序列分析1--生成和导出时间序列数据

时间序列数据的生成 直接录入 1.行录入 ts.(price,startc(2015,1),frequency 12) # price为时间序列变量&#xff0c;start为起始读入时间 frequncy指定每年读入的数据的频率&#xff0c;frequncy4为季度数据、frequncy52为星期数据 2.列录入 scan() 1:101 ....6:7 7:…...

HarmonyOS应用开发—资源分类与访问

应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同的设备或配置中的表…...

C++中的转换构造函数

在 C/C++ 中,不同的数据类型之间可以相互转换。无需用户指明如何转换的称为自动类型转换(隐式类型转换),需要用户显式地指明如何转换的称为强制类型转换。 自动类型转换示例: int a = 6;a = 7.5 + a; 编译器对 7.5 是作为 double 类型处理的,在求解表达式时,先将 a 转换…...

JSP ssm 特殊人群防走失系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 JSP ssm 特殊人群防走失系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源 代码和数据库&#xff0c;系统主要…...

怎么实现一个登录时需要输入验证码的功能

今天给项目换了一个登录页面&#xff0c;而这个登录页面设计了验证码&#xff0c;于是想着把这个验证码功能实现一下吧。 这篇文章就如何实现登录时的验证码的验证功能结合代码进行详细地介绍&#xff0c;以及介绍功能实现的思路。 目录 页面效果 实现思路 生成验证码的控制…...

在android工程中新建Android模块报错

复制了复制正常的build.gradle文件&#xff0c;然后把theme里面的东西改成了下面这个样就好了 <resources xmlns:tools"http://schemas.android.com/tools"><!-- Base application theme. --><style name"Theme.JiQuan" parent"Theme…...

电脑桌面的复选框如何取消

电脑桌面图标的复选框如何取消 1. 概述2. 去掉图标的复选框方法结束语 1. 概述 当你拿到新的电脑开机后&#xff0c;发现桌面上软件应用的图标左上角有个小框&#xff0c;每次点击图标都会显示&#xff0c;并且点击图标时&#xff0c;小框还会打上√&#xff1b; 这个小框的…...

【Unity每日一记】资源加载相关和检测相关

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…...

【数据结构】长篇详解堆,堆的向上/向下调整算法,堆排序及TopK问题

文章目录 堆的概念性质图解 向上调整算法算法分析代码整体实现 向下调整算法算法分析整体代码实现 堆的接口实现初始化堆销毁堆插入元素删除元素打印元素判断是否为空取首元素实现堆 堆排序创建堆调整堆整合步骤 TopK问题 堆的概念 堆就是将一组数据所有元素按完全二叉树的顺序…...

DAQ高频量化平台:引领Ai高频量化交易模式变革

近年来&#xff0c;数字货币投资市场掀起了一股热潮&#xff0c;以&#xff08;BTC&#xff09;为代表的区块链技术带来了巨大的商业变革。数字资产的特点&#xff0c;如无国界、无阶级、无门槛、高流动性和高透明度&#xff0c;吸引了越来越多的人们的关注和认可&#xff0c;创…...

vue3 element plus获取el-cascader级联选择器选中的当前结点的label值 附vue2获取当前label

各位大佬&#xff0c;有时我们在处理级联选择组件数据时&#xff0c;不仅需要拿到id,还需要拿到label名称&#xff0c;但是通常组件直接绑定的是id,所以就需要我们用别的方法去拿到label,此处官方是有这个方法的&#xff0c;具体根据不同的element 版本进行分别处理。 VUE3 e…...

Spring Boot常见面试题

Spring Boot简介 Spring Boot 是由 Pivotal 团队提供&#xff0c;用来简化 Spring 应用创建、开发、部署的框架。它提供了丰富的Spring模块化支持&#xff0c;可以帮助开发者更轻松快捷地构建出企业级应用。Spring Boot通过自动配置功能&#xff0c;降低了复杂性&#xff0c;同…...

分块矩阵求逆

另可参考Block matrix on Wikipedia2018.4.3 补充补充两个参考文献&#xff0c;都是对工科很实用的矩阵手册&#xff1a;D. S. Bernstein, Matrix mathematics: Theory, facts, and formulas with application to linear systems theory. Princeton, NJ: Princeton University …...

Python 文件写入操作

视频版教程 Python3零基础7天入门实战视频教程 w模式是写入&#xff0c;通过write方法写入内容。 # 打开文件 模式w写入&#xff0c;文件不存在&#xff0c;则自动创建 f open("D:/测试3.txt", "w", encoding"UTF-8")# write写入操作 内容写入…...

【Spring Boot系列】- Spring Boot侦听器Listener

【Spring Boot系列】- Spring Boot侦听器Listener 文章目录 【Spring Boot系列】- Spring Boot侦听器Listener一、概述二、监听器Listener分类2.1 监听ServletContext的事件监听器2.2 监听HttpSeesion的事件监听器2.3 监听ServletRequest的事件监听器 三、SpringMVC中的监听器3…...

JavaScript速成课—事件处理

目录 一.事件类型 1.窗口事件 2.表单元素事件 3.图像事件 4.键盘事件 5.鼠标事件 二.JavaScript事件处理的基本机制 三.绑定事件的方法 1.DOM元素绑定 2.JavaScript代码绑定事件 3.监听事件函数绑定 四.JavaScript事件的event对象 1.获取event对象 2.鼠标坐标获取…...

【入门篇】ClickHouse最优秀的开源列式存储数据库

文章目录 一、什么是ClickHouse&#xff1f;OLAP场景的关键特征列式数据库更适合OLAP场景的原因输入/输出CPU 1.1 ClickHouse的定义与发展历程1.2 ClickHouse的版本介绍 二、ClickHouse的主要特性2.1 高性能的列式存储2.2 实时的分析查询2.3 高度可扩展性2.4 数据压缩2.5 SQL支…...

【C++ Exceptions】异常处理的成本

最低成本 exception是C的一部分&#xff0c;编译器必须支持。即使从未使用任何异常处理机制&#xff0c;也必须付出一些空间放置某些数据结构&#xff0c;付出一些时间随时保持那些数据结构的正确性。 第二种成本&#xff1a;来自try语句块 避免非必要的try语句块。 粗略估计&a…...

API接口:原理、实现及应用

API&#xff08;Application Programming Interface&#xff09;接口是现代软件开发中不可或缺的一部分。它们提供了一种机制&#xff0c;使得不同的应用程序和服务可以相互通信&#xff0c;共享数据和功能。在这篇文章中&#xff0c;我们将探讨API接口的原理、实现及应用&…...

武清做网站/郑州百度快照优化

转自 : http://apps.hi.baidu.com/share/detail/37687288 登录 Ubuntu 以后 , 开始用命令行进行逐一安装 : 安装 apache 服务 sudo apt-get install apache2 安装 php5 sudo apt-get install php5  apache 关联 php5 sudo apt-get install libapache2-mod-php5 启动 apache s…...

自适应网站制作方案/西安整站优化

不知道有没有效果&#xff0c;先转记下来吧。 1、高血压&#xff1a;用玉米穗上的须熬水当茶喝&#xff0c;半月即愈。 2、气管炎:喝大豆腐水,连续喝多日;神奇般的根除;佛教释永空提供 3、关节炎&#xff1a;北京医生&#xff1a;张建明 用野线麻叶裹住关节&#xff0c;多用…...

建设海外网站/做百度推广的公司电话号码

高考成绩公布后&#xff0c;很多家长和学生咨询我们&#xff0c;湖南高考个人成绩排名位次如何查询&#xff1a;湖南高考成绩排名&#xff0c;可以通过省招生考试院发布的湖南一分一段表来查询&#xff0c;也可以到聚志愿网站直接输入分数查询&#xff0c;一分一段它显示每一个…...

做问卷的网站哪个好/注册城乡规划师报考条件

问题&#xff1a; This application is currently offline. To enable the application, remove the app_offline.htm file from the application root directory PS&#xff1a;用Visual Studio 2010运行网页时&#xff0c;突然弹出以下症状 解决方案&#xff1a;原本以为是VS…...

做营销型网站 推广的好处/百度旗下产品

阅读本文大概需要 6.8 分钟。Linux 系统大家一定不陌生&#xff0c;学习工作中肯定会和 Linux 打交道。不过谈及 Linux&#xff0c;给人的第一印象可能就是黑乎乎的命令行&#xff0c;乱七八糟的文件夹&#xff0c;甚至安装软件都不知道是怎么安装上去的。其实这些都是用惯了 W…...

2022年深圳在建工程查询/莱阳seo外包

刚接触VC编程的朋友往往对许多数据类型的转换感到迷惑不解&#xff0c;本文将介绍一些常用数据类型的使用。我们先定义一些常见类型变量借以说明int i 100;long l 2001;float f300.2;double d12345.119;char username[]"程佩君";char temp[200];char *buf;CString …...