【寸铁的刷题笔记】图论、bfs、dfs

【寸铁的刷题笔记】图论、bfs、dfs

大家好 我是寸铁👊
金三银四图论基础结合bfsdfs是必考的知识点✨
快跟着寸铁刷起来!面试顺利上岸👋
喜欢的小伙伴可以点点关注 💝


🌞详见如下专栏🌞

🍀🍀🍀寸铁的刷题笔记🍀🍀🍀


200. 岛屿数量

考点

递归、dfs

思路

思路:遍历二维数组,遇到陆地则计数器加1
然后,向该陆地四个方向进行搜索。
遇到边界则停止搜索,如果搜索到的网格为陆地,则说明该网格和遍历到的陆地连通
同时,把该搜索到的陆地'1',置为海洋'0'
由于之前遍历二维数组时遇到陆地时计数器加1,由于连通,算作1个岛屿。
这样就避免下次遍历二维数组时重复遍历陆地,导致岛屿数量多算了。

代码

class Solution {/*思路:遍历二维数组,遇到陆地则计数器加1然后,向该陆地上、下、左、右四个方向进行搜索。遇到边界则停止搜索,如果搜索到的网格为陆地,则该网格和遍历到的陆地连通。同时,把该搜索到的陆地'1',置为海洋'0'由于之前遍历二维数组时遇到陆地时计数器加1,由于连通,算作1个岛屿。这样就避免下次遍历二维数组时,重复遍历陆地,导致岛屿数量多算了。*/public int numIslands(char[][] grid) {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'){//如果说遍历到的节点是陆地'1'dfs(grid , i , j);//则调用递归函数将该陆地周围的陆地进行置0操作count++;//陆地数量++   }      }}return count;//返回陆地的数量}public void dfs(char [][]grid , int i , int j){//边界条件,遇到边界则搜索停下来。if(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == '0')return;//将陆地周围联通的陆地进行置0 , 避免重复遍历,统计陆地的数量不正确。grid[i][j] = '0';//向上、下、左、右四个方向进行遍历,把能走通的陆地进行置0,避免重复遍历。//上dfs(grid , i -1 , j);//下dfs(grid , i + 1 , j);//左dfs(grid , i , j - 1);//右dfs(grid , i , j + 1);}
}

130. 被围绕的区域

考点

递归、dfs

思路

题目描述

这道题是让我们寻找所有被X围绕的区域,并将这块区域中的所有的'OX进行填充。

转换问题

那么怎么样去寻找所有被X围绕的区域呢?
直接做肯定不好做,不妨反过来思考,什么样的才是不被X围绕的区域呢?


在这里插入图片描述

观察题目图形,我们发现如果O位于棋盘边界的位置,则说明O不被X所围绕,与外界连通。

那么问题就转换为去搜索从边界的O开始连通的O区域,这一部分连通的区域必定是不满足条件的,也就是不用替换为X的。
所以,我们从边界的位置出发,去搜索从边界的O开始连通的O区域,并把搜索过的O标记为*,避免后面被重复遍历

如下图绿色为棋盘的边界部分

在这里插入图片描述


复原操作

最后,对棋盘的字符进行复原操作,把标记的*复原为X
剩下的O则为被包围的区域,进行替换为X即可。


代码

class Solution {/*思路:这道题是让我们寻找所有被'X'围绕的区域,并将这块区域中的所有'O'用'X'进行填充。那么,怎么样去寻找所有被'X'围绕的区域呢?直接做肯定不好做,不妨反过来思考,什么样的才是不被'X'围绕的区域呢?观察图形,我们发现如果O位于棋盘边界的位置,则说明'O'不被'X'所围绕。那么问题就转换为去搜索从边界的'O'开始连通的'O'区域,这一部分连通的区域必定是不满足条件的,也就是不用替换为'X'的。所以,我们从边界的位置出发,去搜索从边界的'O'开始连通的'O'区域,并把搜索过的'O'标记为'*',避免后面被重复遍历。最后,对棋盘的字符进行复原操作,把标记的'*'复原为'X'。剩下的'O'则为被包围的区域,进行替换为'X'即可。*/int m;//棋盘的行数int n;//棋盘的列数public void solve(char[][] board) {m = board.length;//行的长度n = board[0].length;//列的长度for(int i = 0; i < m; i++){dfs(board , i , 0);//每一行的第一个位置dfs(board , i , n - 1);//每一行的最后一个位置  }for(int i = 1; i < n - 1; i++){dfs(board , 0 , i);//第一行除了头尾之外的位置dfs(board , m - 1, i);//最后一行除了头尾之外的位置}//dfs处理完毕后,再进行棋盘复原操作for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){//如果说最后的棋盘为O 则直接进行赋值为X即可if(board[i][j] == 'O')board[i][j] = 'X';//把最后棋盘中与外界连通的标记 * 替换为 Oelse if(board[i][j] == '*')board[i][j] = 'O';}}}//寻找与外界棋盘O字符连通的区域public void dfs(char [][]board , int i , int j){//如果说越界了或者说之前被标记为'*'(已经被遍历过)或者是'X'则停止搜索if(i < 0 || j < 0 || i >= m || j >= n || board[i][j] == '*' || board[i][j] == 'X')return;board[i][j] = '*'; //标记为* 表示与外界连通并且这个位置已经被遍历过了,不再重复遍历。//上dfs(board , i - 1 , j);//下dfs(board , i + 1 , j);//左dfs(board , i , j - 1);//右dfs(board , i , j + 1);}
}

133. 克隆图

考点

哈希表、bfs

思路

思想: bfs,宽搜。
从起点节点开始出发,入队,出队,将该起点节点的邻接节点入队,并标记被搜索过(哈希表记录
再弹出当前队列的节点,入队,并继续标记其邻接节点。
依次一层一层的搜索下去,直至最后队列为,说明已经拷贝完图的所有节点。

代码

/*
// Definition for a Node.
class Node {public int val;public List<Node> neighbors;public Node() {val = 0;neighbors = new ArrayList<Node>();}public Node(int _val) {val = _val;neighbors = new ArrayList<Node>();}public Node(int _val, ArrayList<Node> _neighbors) {val = _val;neighbors = _neighbors;}
}
*/class Solution {public Node cloneGraph(Node node) {/*思想:bfs,宽搜。从起点节点开始出发,入队,出队,将该起点节点的邻接节点入队,并标记被搜索过。再弹出当前队列的节点,入队,并继续标记其邻接节点。依次一层一层的搜索下去,直至最后队列为空,说明已经拷贝完图的所有节点。*/if(node == null)return null;//空节点不拷贝Node []cloneNodes = new Node[110];//存储的是每一个已经拷贝(克隆)的节点,标记已被搜索过cloneNodes[node.val] = new Node(node.val);//克隆起点节点Queue<Node>queue = new LinkedList<>();//存储bfs的队列queue.offer(node); //起点节点入队Node cur; // 记录当前处理的节点while(!queue.isEmpty()){cur = queue.poll(); //从队列中获取一个待处理的节点Node cloneNode = cloneNodes[cur.val];//待处理的节点一定是克隆好的,直接获取其克隆节点for(Node neighbor : cur.neighbors){if(cloneNodes[neighbor.val] == null){//如果邻接节点未拷贝则进行拷贝cloneNodes[neighbor.val] = new Node(neighbor.val);queue.offer(neighbor);//邻接节点入队,用于下一轮的节点获取。}//克隆节点的邻居添加入遍历过的拷贝节点的邻接节点cloneNode.neighbors.add(cloneNodes[neighbor.val]);}}//返回克隆节点的记录数组即可return cloneNodes[node.val];}
}

207. 课程表

考点

bfs、拓扑排序

思路

思想: 要想修一门课程,则需要先修它的先修课程。
所以, 我们可以把他看成是一个有向无环图
判断最后每个点是不是入度、出度为0节点数等于课程数即可。

做法

  1. 先将先修课程向要修课程连一条边,同时记录要修课程的入度

  2. 再统计每个点的入度,在bfs时,将待修课程节点的入度--

  3. 最后, 判断入度为0节点数是否等于课程数
    等于则说明可以完成所有课程的学习。
    不等于则说明存在,陷入死循环中,无法完成课程的学习。


代码

class Solution {/*思想: 要想修一门课程,则需要先修它的先修课程。所以, 我们可以把他看成是一个有向无环图。判断最后每个点是不是入度、出度为0的节点数等于课程数即可。先将先修课程向要修课程连一条边再统计每个点的入度,在bfs搜索时,将先修课程节点的出度--最后, 入读和出度都为0,则说明可以完成所有课程的学习。最后, 判断入度、出度为0的节点数是否等于课程数。等于则说明可以完成所有课程的学习。不等于则说明存在环,陷入死循环中,无法完成课程的学习。*/public boolean canFinish(int numCourses, int[][] prerequisites) {int []indegress = new int[numCourses];List<List<Integer>>adjacency = new ArrayList<>();Queue<Integer> queue = new LinkedList<>();for(int i = 0; i < numCourses; i++){adjacency.add(new ArrayList<>());}for(int []cp : prerequisites){//要想修0必须先修1//对0而言是入度,对1而言是出度indegress[cp[0]]++;//入度++//先修课程向要修课程向连一条边adjacency.get(cp[1]).add(cp[0]);}//寻找入度为0的点开始进行拓扑排序//入度为0则说明它是可以修的课程for(int i = 0; i < numCourses; i++){if(indegress[i] == 0)queue.add(i);}while(!queue.isEmpty()){//弹出入度为0的节点,说明该课程可以被修。int pre = queue.poll();//同时课程数量--numCourses--;//遍历先修课程的节点for(int cur : adjacency.get(pre)){//出度--//如果说点cur的入度与出度都为0//则队列中添加节点cur,用于下一轮的搜索。if(--indegress[cur] == 0){queue.add(cur);}}}//最后,判断一下是不是课程数等于0//如果说课程数等于0 则代表可以完成所有课程的学习。return numCourses == 0;}
}

210. 课程表 II

考点

bfs、拓扑排序

思路

在课程表题目的基础上,多维护一个数组,用于记录当前弹出的节点的路径(走过的节点)
弹出的节点是入度0的节点,入度0说明为已修的先修课程,并且是先修完的,可以按照这个顺序来。

代码

class Solution {//在课程表题目的基础上,多维护一个数组,用于记录当前弹出的节点的路径//弹出的节点是入度为0的节点,入度为0说明为已修的先修课程,并且是先修完的,可以按照这个顺序来。public int[] findOrder(int numCourses, int[][] prerequisites) {int []indegress = new int[numCourses];//记录每个节点的入度List<List<Integer>>adjacency = new ArrayList<>();//维护一个列表用于存储边Queue<Integer>queue = new LinkedList<>();//创建队列,用于存储节点for(int i = 0; i < numCourses; i++){adjacency.add(new ArrayList<>());//每个节点先添加列表用于存连接的节点(边)}for(int []cp : prerequisites){indegress[cp[0]]++; //要修课程的入度++adjacency.get(cp[1]).add(cp[0]);//将先修课程和待修课程连一条边//用于后续遍历入度为0节点的队列将待修课程的入度--//用于下一轮的循环}//先将入度为0的节点添加入队列for(int i = 0; i < numCourses; i++){if(indegress[i] == 0)queue.add(i);}//创建数组ans,用于记录学完所有课程所安排的学习顺序。int ans[] = new int[numCourses];int index = 0;//数组下标,用于存储学完的课程while(!queue.isEmpty()){int pre = queue.poll();ans[index++]=pre;//入度为0的节点是确保能够修完的先修课程,存到结果数组中。for(int cur : adjacency.get(pre)){//将每个待修课程的入度--if(--indegress[cur] == 0){queue.add(cur);//入度为0则入队}}}//最后的结果是入度均为0//如果说某个节点的入度 > 0 , 则说明不可能修完全部课程, 存在一个环。//如[[0,1],[1,0]]//这里无法找到一个入度为0的节点,存在一个环。for(int i = 0; i < indegress.length; i++){if(indegress[i] > 0)return new int[0];//返回一个空数组即可}//等价写法如下://如果说index不等于课程数量,则说明存在入度不为0的点,也就是环。// if(index != numCourses){//     return new int[0];// } return ans;//返回结果数组}
}

看到这里的小伙伴,恭喜你又掌握了一个技能👊
希望大家能取得胜利,坚持就是胜利💪
我是寸铁!我们下期再见💕

往期好文💕

保姆级教程

【保姆级教程】Windows11下go-zero的etcd安装与初步使用

【保姆级教程】Windows11安装go-zero代码生成工具goctl、protoc、go-zero

【Go-Zero】手把手带你在goland中创建api文件并设置高亮


报错解决

【Go-Zero】Error: user.api 27:9 syntax error: expected ‘:‘ | ‘IDENT‘ | ‘INT‘, got ‘(‘ 报错解决方案及api路由注意事项

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案

【Go-Zero】【error】 failed to initialize database, got error Error 1045 (28000):报错解决方案

【Go-Zero】Error 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)报错解决方案

【Go-Zero】type mismatch for field “Auth.AccessSecret“, expect “string“, actual “number“报错解决方案

【Go-Zero】Error: user.api 30:2 syntax error: expected ‘)‘ | ‘KEY‘, got ‘IDENT‘报错解决方案

【Go-Zero】Windows启动rpc服务报错panic:context deadline exceeded解决方案


Go面试向

【Go面试向】defer与time.sleep初探

【Go面试向】defer与return的执行顺序初探

【Go面试向】Go程序的执行顺序

【Go面试向】rune和byte类型的认识与使用

【Go面试向】实现map稳定的有序遍历的方式

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【办公类-21-04】20240227单个word按“段落数”拆分多个Word(三级育婴师操作参考题目 有段落文字和表格 1拆13份)

作品展示 背景需求&#xff1a; 最近学育婴师&#xff0c;老师发了一套doc操作参考 但是老师是一节节授课的&#xff0c;每节都有视频&#xff0c;如果做在一个文档里&#xff0c;会很长很长&#xff0c;容易找不到。所以我需要里面的单独文字的docx。 以前的方法是 1、打开源…

FL Studio 21.2.3.3586 for Mac中文版新功能介绍及2024年最新更新日志

如果你正计划学习音乐制作&#xff0c;一款强大且易学的音乐制作软件是必不可少的。由于很多小伙伴对音乐制作软件没有实际体验过&#xff0c;到底选择哪一款软件最合适成为当下最纠结的问题。 这里为大家推荐一款功能强大且适合新手小伙伴的音乐编曲软件—FL Studio 21.2.3.35…

GPT 的基础 - T(Transformer)

我们知道GPT的含义是&#xff1a; Generative - 生成下一个词 Pre-trained - 文本预训练 Transformer - 基于Transformer架构 我们看到Transformer模型是GPT的基础&#xff0c;这篇博客梳理了一下Transformer的知识点。 BERT:通过自监督的方式,在大规模语料上预训练得到的Tran…

react 路由的基本原理及实现

1. react 路由原理 不同路径渲染不同的组件 有两种实现方式 ● HasRouter 利用hash实现路由切换 ● BrowserRouter 实现h5 API实现路由切换 1. 1 HasRouter 利用hash 实现路由切换 1.2 BrowserRouter 利用h5 Api实现路由的切换 1.2.1 history HTML5规范给我们提供了一个…

概率基础——正态分布

概率基础——正态分布 介绍 正态分布&#xff0c;又称高斯分布&#xff0c;是统计学中最重要的连续概率分布之一。它在自然界和人类活动中都有广泛的应用&#xff0c;被广泛用于描述各种自然现象和社会现象。正态分布的曲线呈钟形&#xff0c;以其特有的形态而著称&#xff0…

Ubuntu常用状态命令

目录 一、温度 1&#xff0c;查看CPU温度 2&#xff0c;查看硬盘温度 二、CPU状态 1&#xff0c;显示CPU的详细信息&#xff0c;包括型号、频率、缓存等 2&#xff0c;显示CPU架构、CPU核心数、线程数、频率等信息 三、登录状态 1&#xff0c;查看成功登录的用户 2&am…

day02_前后端环境搭建(前端工程搭建,登录功能说明,后端项目搭建)

文章目录 1. 软件开发介绍1.1 软件开发流程1.2 角色分工1.3 软件环境1.4 系统的分类 2. 尚品甄选项目介绍2.1 电商基本概念2.1.1 电商简介2.1.2 电商模式B2BB2CB2B2CC2BC2CO2O 2.2 业务功能介绍2.3 系统架构介绍2.4 前后端分离开发 3. 前端工程搭建3.1 Element-Admin简介3.2 El…

线性表——单链表的增删查改

本节复习链表的增删查改 首先&#xff0c; 链表不是连续的&#xff0c; 而是通过指针联系起来的。 如图&#xff1a; 这四个节点不是连续的内存空间&#xff0c; 但是彼此之间使用了一个指针来连接。 这就是链表。 现在我们来实现链表的增删查改。 目录 单链表的全部接口…

MySQL:开始深入其数据(一)DML

在上一章初识MySQL了解了如何定义数据库和数据表&#xff08;DDL&#xff09;&#xff0c;接下来我们开始开始深入其数据,对其数据进行访问&#xff08;DAL&#xff09;、查询DQL&#xff08;&#xff09;和操作(DML)等。 通过DML语句操作管理数据库数据 DML (数据操作语言) …

Qt篇——QTableWidget保存表格数据到Excel文件中,读Excel内容到QTableWidget

表格和excel例子如下图所示&#xff1a; 一、QTableWidget保存表格数据到Excel文件中 代码如下&#xff1a; &#xff08;pro文件中添加QT axcontainer&#xff09; #include <QAxObject>void MainWindow::saveTableToExcel() {QDateTime current_date_time QDateTi…

路由器端口映射如何配置?

在网络通信中&#xff0c;路由器是一个重要的设备&#xff0c;它负责将数据包从一个网络传输到另一个网络。路由器的端口映射配置是一种重要的设置&#xff0c;可以使外部网络中的计算机通过访问路由器上的特定端口与内部网络中的计算机进行通信。本文将介绍什么是路由器端口映…

4核8G服务器选阿里云还是腾讯云?价格性能对比

4核8G云服务器多少钱一年&#xff1f;阿里云ECS服务器u1价格955.58元一年&#xff0c;腾讯云轻量4核8G12M带宽价格是646元15个月&#xff0c;阿腾云atengyun.com整理4核8G云服务器价格表&#xff0c;包括一年费用和1个月收费明细&#xff1a; 云服务器4核8G配置收费价格 阿里…

全面升级!Apache HugeGraph 1.2.0版本发布

图数据库以独特的数据管理和分析能力&#xff0c;在企业数智化转型的过程中正在成为数据治理的核心&#xff0c;根据IDC调研显示&#xff0c;95%的企业认为图数据库是重要的数据管理工具&#xff0c;超过65%的厂商认为在业务上图数据库优于其他选择&#xff0c;尤其是在金融风控…

Centos6安装PyTorch要求的更高版本gcc

文章目录 CentOS自带版本安装gcc 4的版本1. 获取devtoolset-8的yum源2. 安装gcc3. 版本检查和切换版本 常见问题1. 找不到包audit*.rpm包2. 找不到libcgroup-0.40.rc1-27.el6_10.x86_64.rpm 的包4. cc: fatal error: Killed signal terminated program cc1plus5. pybind11/pybi…

工具使用-pwncat

pwncat是一个命令和控制框架&#xff0c;可以将基本的反向或绑定shell转化为一个功能齐全的利用平台。然后&#xff0c;它将尝试在远程主机上启动一个伪终端&#xff0c;并为您提供原始终端访问。 但pwncat不止于此。除了自动的获取全交互式终端外&#xff0c;pwncat还提供了一…

微服务-商城订单服务项目

文章目录 一、需求二、分析三、设计四、编码4.1 商品服务4.2 订单服务4.3 分布式事务4.4 订单超时 商品、购物车 商品服务&#xff1a; 1.全品类购物平台 SPU:Standard Product Unit 标准化产品单元。是商品信息聚合的最小单位。是一组可复用、易检索的标准化信息的集合&#x…

求两个向量之间的夹角

求两个向量之间的夹角 介绍Unity的API求向量夹角Vector3.AngleVector3.SignedAngle 自定义获取方法0-360度的夹角 总结 介绍 求两个向量之间的夹角方法有很多&#xff0c;比如说Unity中的Vector3.Angle&#xff0c;Vector3.SignedAngle等方法&#xff0c;具体在什么情况下使用…

4_透镜畸变

理论上讲&#xff0c;是可能定义一种透镜而不引入任何畸变的。然而现实世界没有完美的透镜。这主要是制造上的原因&#xff0c;因为制作一个“球形”透镜比制作一个数学上理想的透镜更容易。而且从机械方面也很难把透镜和成像仪保持平行。下面主要描述两种主要的透镜畸变并为他…

Python之No module named xxx类问题解决思路(三十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Java集合基础梳理(集合体系+ArrayList)

目录 Java集合体系 为什么要使用集合类 ? 如何选用集合? 哪些集合类是线程安全的&#xff1f;哪些不安全&#xff1f; 快速失败(fail-fast)和安全失败(fail-safe)的区别是什么&#xff1f; 遍历的同时修改一个List有几种方式 ArrayList 如何进行元素的遍历操作&#x…