【Java实习面试算法冲刺】图论
第9类题型图论问题背景为什么图论题你总觉得自己会 BFS / DFS一到面试还是容易把题型判断错很多实习面试里的图论题表面根本不写“图”这个字。它可能长成二维矩阵像200. 岛屿数量、994. 腐烂的橘子也可能长成依赖关系像207. 课程表。真正让人失分的地方往往不是代码敲不出来而是你没有在前 30 秒里判断清楚这题的点和边分别是什么。这是在求连通块、最短扩散层数还是在判断有没有环。该用 DFS、BFS还是拓扑排序。如果你现在的状态是“看过图论模板但一遇到矩阵题和依赖题还是会犹豫”那这一类题必须单独练透。读完这篇你至少要把 4 件事固定下来先把题目抽象成图、先决定遍历方式、访问标记要在什么时候打、依赖题要怎么建邻接表和入度表。文章目录第9类题型图论问题背景为什么图论题你总觉得自己会 BFS / DFS一到面试还是容易把题型判断错1. 核心知识点2. 图论题型选择表DFS / BFS / 拓扑排序什么时候用3. 动画辅助理解图论题先建模再决定怎么遍历4. 用样例手推 DFS / 拓扑排序先手推 DFS200. 岛屿数量再手推拓扑排序207. 课程表5. 这类题在面试里考什么6. 高频题清单7. 这类题最容易犯的 4 个错误8. 代表题精讲 1题目思路Java 代码复杂度边界提醒如果这是面试现场你可以这样说9. 代表题精讲 2题目思路Java 代码复杂度边界提醒如果这是面试现场你可以这样说10. 其余题模板与关键片段[994. 腐烂的橘子](https://leetcode.cn/problems/rotting-oranges/)[733. 图像渲染](https://leetcode.cn/problems/flood-fill/)11. 图论题先判断什么12. 错题本记录方式13. 面试前 3 分钟速记14. 快速验证同一套判断能不能落到 200 / 994 / 20715. 本地样例验证结果16. 最后总结图论题真正难的不是模板而是建模速度1. 核心知识点实习面试里的图论最常见的不是 Dijkstra 或 Floyd而是下面 3 类基础模型网格 DFS常见于“数连通块”“把一整片区域染色”。多源 BFS常见于“按层扩散”“求最少几轮传播到位”。拓扑排序常见于“课程依赖”“任务先后关系”“判断是否有环”。你可以先把它们理解成三个固定问法如果题目在问“这一整片算一个块吗”优先想 DFS / BFS。如果题目在问“最少经过几步扩散完成”优先想 BFS。如果题目在问“这些依赖能不能都做完”优先想拓扑排序。2. 图论题型选择表DFS / BFS / 拓扑排序什么时候用题目特征常见问题优先解法你在面试里要先说清楚什么二维矩阵上下左右连通有几个连通块、整片区域是否连通DFS / BFS一个格子是不是一个节点连边规则是什么从多个起点同时扩散最少几轮传播完成、最短层数BFS为什么要按层处理初始队列里有哪些起点课程 / 任务存在先后依赖是否有环、能否完成全部任务拓扑排序邻接表怎么建入度表示什么真正高频的失误不是“不会写”而是“题型选错”200. 岛屿数量本质是数连通块不是在求最短路径。994. 腐烂的橘子本质是多源扩散不适合拿 DFS 去硬做分钟数。207. 课程表本质是判断依赖图里是否有环不是在普通遍历里随便走一遍。3. 动画辅助理解图论题先建模再决定怎么遍历你可以先打开这页分步动画图论建图、入队、访问邻居分步动画这个动画最值得盯住的不是按钮而是 4 个固定动作先说明节点和边怎么定义。再决定起点怎么入栈 / 入队。访问邻居时立刻处理visited避免重复访问。最后根据题目要求统计答案是连通块数量、扩散轮数还是可完成课程数。4. 用样例手推 DFS / 拓扑排序这一节非常重要。图论题如果只看模板不手推状态你在面试里还是容易卡。先手推 DFS200. 岛屿数量样例grid [ [1,1,0,0], [1,0,0,1], [0,0,1,1] ]你可以把每个值为1的格子看成一个陆地节点上下左右相邻就有边。手推过程扫描位置看到什么动作当前岛屿数(0,0)1且未访问岛屿数1从(0,0)开始 DFS把(0,0)、(0,1)、(1,0)全部淹没 / 标记1继续扫描第一、二行已访问陆地或海水跳过1(1,3)1且未访问岛屿数1DFS 扩到(2,3)、(2,2)2扫描结束没有新的未访问陆地返回答案2你在面试里要说清楚的关键点是这题不是“从某个起点找到一条路径”而是“扫描全图遇到新陆地就扩掉整片连通块”。每次 DFS 的目的不是求最短路而是“把这一整片陆地都处理掉避免重复计数”。再手推拓扑排序207. 课程表样例numCourses 4 prerequisites [[1,0],[2,0],[3,1],[3,2]]这表示学1之前先学0学2之前先学0学3之前先学1和2所以邻接表和入度表会变成0 - [1, 2] 1 - [3] 2 - [3] 3 - [] indegree [0, 1, 1, 2]手推过程队列出队课程更新后入度变化已处理课程数[0]01: 1-02: 1-0把1、2入队1[1,2]13: 2-12[2]23: 1-0把3入队3[3]3无后续课程4最后处理课程数等于numCourses说明图里没有环可以学完。你在面试里要强调入度为0的课说明它当前没有前置依赖可以先学。如果图里有环那么环上的课程入度永远不可能全部降到0。所以最后只要比较“处理掉的课程数”和“总课程数”是否相等就能判断能不能学完。5. 这类题在面试里考什么图论题考的不是名词量而是你能不能把题目稳定抽象成“点 边 遍历规则”。面试官通常会看你能不能先判断它是网格图、普通图还是依赖图。你会不会解释为什么该用 DFS、BFS 或拓扑排序。你能不能把visited、邻接表、入度表维护清楚。你是否知道答案统计发生在什么时候是每次发现新连通块时、每一层 BFS 结束时还是拓扑出队时。真正拉开差距的地方在于你不只是把代码敲出来还能解释“为什么这个统计口径正好对应题目要的答案”。6. 高频题清单题目来源难度高频属性200. 岛屿数量LeetCode 热题 100Medium高频994. 腐烂的橘子LeetCode 热题 100Medium高频207. 课程表LeetCode 热题 100Medium高频733. 图像渲染面试经典 150Easy基础高频7. 这类题最容易犯的 4 个错误看到矩阵题没有意识到本质上是网格图。visited标记时机错了导致重复入队或重复 DFS。把“求最少几轮扩散”的题写成 DFS结果分钟数不好统计。课程表不会把依赖关系转成邻接表和入度表。8. 代表题精讲 1题目200. 岛屿数量思路这题本质上是“数二维网格里的连通块数量”。扫描整个矩阵时只要看到一个还没处理过的1就说明发现了一座新岛屿此时答案加一然后从这个格子出发 DFS把整片和它连通的陆地全部标记掉。这样后面再扫到这片区域时就不会重复计数。这题为什么适合 DFS每次进入 DFS目标都是“扩完这一整片连通块”。不需要维护层数也不需要比较最短路径。递归写法足够直接面试里表达也最顺。Java 代码classSolution{privatestaticfinalint[][]DIRS{{1,0},{-1,0},{0,1},{0,-1}};publicintnumIslands(char[][]grid){introwsgrid.length;intcolsgrid[0].length;intislands0;for(introw0;rowrows;row){for(intcol0;colcols;col){if(grid[row][col]1){islands;dfs(grid,row,col);}}}returnislands;}privatevoiddfs(char[][]grid,introw,intcol){if(row0||rowgrid.length||col0||colgrid[0].length){return;}if(grid[row][col]!1){return;}grid[row][col]0;for(int[]dir:DIRS){dfs(grid,rowdir[0],coldir[1]);}}}复杂度时间复杂度O(m * n)空间复杂度递归栈最坏O(m * n)边界提醒这题最容易错的地方有三个忘了在 DFS 里把当前格子标记掉导致重复访问。只从一个起点出发却忘了外层还要扫描整张图。把对角线也当成连通方向结果答案算多。这题默认只看上下左右不看斜对角。这个细节如果面试里不先说容易被追问。如果这是面试现场你可以这样说这题我会把矩阵看成一个网格图每个陆地格子是节点上下左右相邻就有边。扫描矩阵时只要遇到一个还没处理过的1就说明发现了一整片新连通块答案加一然后用 DFS 把这片陆地全部标记掉避免后面重复计数。9. 代表题精讲 2题目207. 课程表思路这题问的是所有课程依赖关系里是否存在环。只要没有环就能完成所有课程。最稳的做法是拓扑排序建邻接表记录一门课学完后能解锁哪些课。统计每门课当前的入度。把所有入度为0的课程入队。每次弹出一门课就把它指向的后续课程入度减一。如果某门课入度减到0说明它现在没有前置依赖了可以入队。最后比较处理课程数和总课程数。Java 代码importjava.util.ArrayDeque;importjava.util.ArrayList;importjava.util.List;importjava.util.Queue;classSolution{publicbooleancanFinish(intnumCourses,int[][]prerequisites){ListListIntegergraphnewArrayList();for(inti0;inumCourses;i){graph.add(newArrayList());}int[]indegreenewint[numCourses];for(int[]edge:prerequisites){intcourseedge[0];intpreedge[1];graph.get(pre).add(course);indegree[course];}QueueIntegerqueuenewArrayDeque();for(inti0;inumCourses;i){if(indegree[i]0){queue.offer(i);}}intfinished0;while(!queue.isEmpty()){intcurrentqueue.poll();finished;for(intnext:graph.get(current)){indegree[next]--;if(indegree[next]0){queue.offer(next);}}}returnfinishednumCourses;}}复杂度时间复杂度O(V E)空间复杂度O(V E)边界提醒这题最容易误判的地方是以为“遍历过所有点”就够了但实际上关键是能不能按依赖顺序不断找到入度为0的点。邻接表方向建反了。这里必须是pre - course表示学完前置课程后才能解锁后续课程。忘了最后比较finished numCourses导致即使有环也返回了true。如果这是面试现场你可以这样说这题本质是在判断依赖图里有没有环。我会用拓扑排序先统计每门课的入度把所有入度为0的课入队再不断出队并更新后续课程的入度。如果最后能处理掉全部课程说明图里没有环否则就说明有课程被环卡住了。10. 其余题模板与关键片段994. 腐烂的橘子这题的关键不是“会不会遍历”而是“为什么必须按层扩散”。所有初始腐烂橘子都要先入队因为它们是同一时刻的多个起点。每处理完一层队列才代表过去了 1 分钟。因此这题优先想多源 BFS而不是 DFS。关键片段while(!queue.isEmpty()fresh0){intsizequeue.size();minutes;for(inti0;isize;i){int[]currentqueue.poll();for(int[]dir:DIRS){intnextRowcurrent[0]dir[0];intnextColcurrent[1]dir[1];if(isFresh(grid,nextRow,nextCol)){grid[nextRow][nextCol]2;fresh--;queue.offer(newint[]{nextRow,nextCol});}}}}733. 图像渲染这题是最基础的网格 DFS / BFS 题。面试里如果你第一次接触图论题往往会先从它开始热身。11. 图论题先判断什么真正动手写代码前你可以先问自己 4 个问题这题里的节点是什么是格子、课程还是普通图节点。边怎么连是上下左右、依赖关系还是邻接关系。题目要的是连通块数量、最短扩散层数还是是否存在环。visited应该在什么时候标记是入队时、出队时还是进入 DFS 时。这 4 个问题一旦先说清楚图论题的大部分思路就已经定下来了。12. 错题本记录方式图论题建议重点记这题里的点和边分别是什么。我为什么判断该用 DFS / BFS / 拓扑排序。visited或入度表是怎么维护的。这题的答案到底是在什么时候统计出来的。13. 面试前 3 分钟速记矩阵上下左右扩散优先想网格图。数连通块常见 DFS / BFS。求最少几轮扩散优先想多源 BFS。课程依赖、先修关系优先想拓扑排序。图题一上来先说节点、边、访问标记。14. 快速验证同一套判断能不能落到 200 / 994 / 207你在面试前可以用下面这张表做最后自检看看自己是不是真的把这类题吃透了题目先识别什么正确做法为什么不是别的做法200. 岛屿数量网格图、数连通块DFS / BFS它不是求最短层数不需要按层统计分钟994. 腐烂的橘子多起点同时扩散多源 BFS题目要最少几分钟天然需要按层推进207. 课程表依赖关系、有无环拓扑排序核心不是遍历所有点而是看能否持续找到入度为0的点如果你能在 30 秒内把这三题都归到正确模型并说明“为什么不用另两种”那这类图论高频题基本就已经掌握到位了。15. 本地样例验证结果为了避免“思路看起来对但代码细节有误”我按文中的200和207代码思路做了本地样例验证输出如下numIslands2 canFinishtrue这两行结果分别对应200. 岛屿数量的手推样例最终得到2座岛。207. 课程表的依赖样例最终可以完成全部课程因此返回true。如果你自己复盘时写出的结果和这里不一致优先检查 3 个地方DFS 是否真的把整片陆地都标记掉了、拓扑排序的边方向有没有建反、入度减到0时有没有及时入队。16. 最后总结图论题真正难的不是模板而是建模速度图论题最容易让人慌的地方是题面不一定直接告诉你“这是图”。但只要你养成固定顺序很多题都会变简单先找节点和边。再判断这是连通块、扩散层数还是依赖有环。然后决定用 DFS、BFS还是拓扑排序。最后明确答案统计发生在什么时候。面试里你只要能把这条链路说顺图论题就不会再只是“背过几个模板”而是真正掌握了这一类题的公共骨架。上期速递【Java实习面试算法冲刺】回溯感谢阅读记得点赞、关注、收藏欢迎各位评论区交流

相关新闻

硬盘文件系统系列专题之二:NTFS的元数据王国与数据寻踪

硬盘文件系统系列专题之二:NTFS的元数据王国与数据寻踪

1. NTFS文件系统的核心架构:MFT与元数据文件当你把一块硬盘格式化成NTFS分区时,系统会在磁盘上建立一个精密的"档案管理局"——这个管理局的核心就是主文件表(MFT)。想象一下MFT就像图书馆的总目录,而$MFT、…

2026/7/14 23:22:46 阅读更多 →
Erlang列表与字符串处理:RabbitMQ源码调试的核心技巧

Erlang列表与字符串处理:RabbitMQ源码调试的核心技巧

在深入 RabbitMQ 源码的过程中,很多开发者会遇到一个共同的瓶颈:Erlang 语言基础不扎实。特别是当涉及到 List 操作、列表推导式和字符串处理时,一些看似简单的语法细节往往成为调试过程中的"隐形杀手"。本文将系统讲解 Erlang 中 …

2026/7/14 23:22:46 阅读更多 →
PyTorch LSTM 模型构建与时间序列预测实战

PyTorch LSTM 模型构建与时间序列预测实战

1. LSTM与时间序列预测入门指南时间序列数据就像我们生活中的心电图,每一秒都在记录着变化。从股票价格的波动到城市客流量的起伏,这些数据背后都藏着宝贵的规律。而LSTM(长短期记忆网络)正是解读这些规律的利器,它能像…

2026/7/14 23:20:45 阅读更多 →

最新新闻

【ABAP】转换例程解析:从定义到应用,一篇就够了

【ABAP】转换例程解析:从定义到应用,一篇就够了

目录 前言 一、什么是转换例程? 为什么需要转换例程? 二、例程在哪里定义? 如何找到它? 表级查询方式 三、如何发现代码中的转换例程? 四、如何在程序中强制使用/调用(应用)转换例程&am…

2026/7/15 0:23:09 阅读更多 →
【限时解密】ChatGPT私域社群GMV提升217%的底层逻辑:基于27个真实社群的NLP情感分析报告

【限时解密】ChatGPT私域社群GMV提升217%的底层逻辑:基于27个真实社群的NLP情感分析报告

更多请点击: https://codechina.net 第一章:【限时解密】ChatGPT私域社群GMV提升217%的底层逻辑:基于27个真实社群的NLP情感分析报告 通过对27个垂直行业(教育、SaaS、跨境电商、知识付费等)的活跃ChatGPT私域社群进行…

2026/7/15 0:23:09 阅读更多 →
OpenHarmony 关系型数据库 RDB 完整封装(API Version23 本地持久化数据库)

OpenHarmony 关系型数据库 RDB 完整封装(API Version23 本地持久化数据库)

摘要RDB 是鸿蒙内置轻量关系型数据库,基于 SQLite 封装,适合存储结构化大量数据(笔记、用户列表、商品数据),相比 Preferences 仅适合简单键值对,RDB 支持表、字段、主键、条件分页查询、多条件筛选、批量增…

2026/7/15 0:21:08 阅读更多 →
为什么同一个问题,AI 每次给出的答案都不一样?

为什么同一个问题,AI 每次给出的答案都不一样?

第一次问 AI,它说方案 A 最合适;刷新后再问,它又推荐方案 B。写文案时,这种变化带来灵感;查事实时,却让人心里没底。同一个问题为什么没有唯一答案?是 AI 随机乱说,还是我们其实没有…

2026/7/15 0:21:08 阅读更多 →
收藏了!1个让零基础小白也能看懂AI的GitHub开源课程,太全了

收藏了!1个让零基础小白也能看懂AI的GitHub开源课程,太全了

前几天有个做运营的朋友跟我说,她想搞明白大模型到底是怎么工作的,结果翻了一堆教程,全是公式和代码,看了三天就放弃了。我跟她说,其实不用那么硬核,有个课程专门给啥都不懂的人设计的,她花了两…

2026/7/15 0:17:07 阅读更多 →
基于STM32的智能家居系统-基于STM32单片机物联网设计【硬件+APP+云平台】

基于STM32的智能家居系统-基于STM32单片机物联网设计【硬件+APP+云平台】

(1)硬件端 1. 环境监测:温度、湿度、空气质量、光照强度等。 2. 家具模拟:门(舵机模拟)、窗(舵机模拟)、灯、风扇,有无线控制和手动控制两种方式; 3. …

2026/7/15 0:15:07 阅读更多 →

日新闻

YOLO11 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

YOLO11 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

前言 本文介绍了面向红外小目标检测的时空特征融合模块——STFFM,用于增强复杂背景下目标与噪声、杂波的区分能力。该方法通过拼接空间特征与时间/运动特征,并结合通道注意力、空间注意力和残差增强机制,实现对关键语义通道与疑似目标区域的…

2026/7/15 0:01:00 阅读更多 →
YOLO26 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

YOLO26 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

前言 本文介绍了面向复杂背景小目标检测的时空特征融合模块——STFFM。该模块通过空间分支与时间/运动分支的特征拼接,引入通道注意力和空间注意力对融合特征进行自适应筛选,并结合残差增强与通道压缩,突出目标区域、抑制背景噪声。我们将 S…

2026/7/15 0:01:00 阅读更多 →
行星减速机为什么能提高扭矩?从功率守恒到输出扭矩校核

行星减速机为什么能提高扭矩?从功率守恒到输出扭矩校核

一、为什么减速以后扭矩会增大 旋转机械的功率、转速和扭矩之间存在以下关系: T 9550 P n 其中: T为扭矩,单位Nm; P为功率,单位kW; n为转速,单位r/min。 在功率基本不变的情况下:…

2026/7/15 0:03:00 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/14 16:53:23 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/14 14:00:13 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/14 7:15:24 阅读更多 →

月新闻