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

面试官问我Floyd算法,我画了张图就讲明白了(附Java代码实现)

用一张图讲透Floyd算法从三重循环到动态规划的精妙拆解面试官推了推眼镜在白板上画出一个带权图能解释下Floyd算法如何计算任意两点间最短路径吗作为过来人我深知这是考察动态规划思想的经典问题。不同于Dijkstra的单源路径计算Floyd算法的精妙之处在于用三层循环解决多源最短路径问题——而理解它的关键在于看透那个看似简单却充满智慧的动态转移方程。1. 从实际问题理解算法本质假设我们正在开发一个城市导航系统需要计算任意两个地标之间的最短行驶距离。图结构中的顶点代表地标边权重表示道路长度。此时如果使用Dijkstra算法需要对每个顶点都执行一次计算时间复杂度达到O(V³)。而Floyd算法通过动态规划的思想用同样时间复杂度一次性解决所有顶点对的最短路径问题。算法核心思想可以概括为逐步允许路径经过更多顶点作为中转站动态更新最短距离。具体来说初始时只允许直达路径不经过任何中转第一步允许路径经过顶点0中转第二步允许路径经过顶点0、1中转...第n步允许路径经过所有顶点中转这种渐进式开放中转站的策略正是动态规划中分阶段解决问题的典型体现。下面这个6顶点图的演变过程展示了算法如何逐步优化路径初始状态只允许直达 A-B: 5 A-C: ∞ A-D: 10 B-A: ∞ B-C: 3 B-D: ∞ C-A: 5 C-B: ∞ C-D: 1 D-A: ∞ D-B: ∞ D-C: 4 允许经过A中转后 A-B: 5 A-C: ∞ A-D: 10 B-A: ∞ B-C: 3 B-D: ∞ C-A: 5 C-B: 10 C-D: 1 # C-B更新为C-A-B5510 D-A: ∞ D-B: ∞ D-C: 42. 动态图解与状态转移方程理解Floyd算法最直观的方式就是观察邻接矩阵的更新过程。我们用一个4×4的矩阵表示图中顶点间的距离其中∞表示不可达// 初始邻接矩阵 int[][] graph { {0, 5, ∞, 10}, {∞, 0, 3, ∞}, {5, ∞, 0, 1}, {∞, ∞, 4, 0} };算法的状态转移方程是理解的关键dist[i][j] min(dist[i][j], dist[i][k] dist[k][j])这个简洁的方程蕴含着动态规划的精髓从i到j的最短路径要么是已知的直达路径要么是通过k中转的路径。让我们拆解k0时的更新过程检查所有i-0-j的路径发现2-0-1的路径长度为5510比原来的∞更优更新dist[2][1]10其他组合如1-0-2需要∞∞不更新用表格展示k从0到3的逐步更新阶段更新的关键路径新距离更新原因k0C-A-B1055 ∞k1A-B-D853 10k2B-C-D431 ∞k3A-D-C (不更新)-104 ∞ (无需更新)3. Java实现与逐行解析下面这个实现不仅计算最短距离还增加了路径重建功能。关键点在于维护两个矩阵距离矩阵和路径前驱矩阵。public class FloydWarshall { private static final int INF Integer.MAX_VALUE; public static void floyd(int[][] graph) { int n graph.length; int[][] dist new int[n][n]; int[][] next new int[n][n]; // 路径重建矩阵 // 初始化 for (int i 0; i n; i) { for (int j 0; j n; j) { dist[i][j] graph[i][j]; next[i][j] (graph[i][j] ! INF i ! j) ? j : -1; } } // 三重循环核心逻辑 for (int k 0; k n; k) { for (int i 0; i n; i) { for (int j 0; j n; j) { if (dist[i][k] ! INF dist[k][j] ! INF dist[i][k] dist[k][j] dist[i][j]) { dist[i][j] dist[i][k] dist[k][j]; next[i][j] next[i][k]; // 更新路径 } } } } printSolution(dist, next); } private static void printSolution(int[][] dist, int[][] next) { System.out.println(最短距离矩阵:); for (int[] row : dist) { for (int val : row) System.out.print((val INF ? ∞ : val) \t); System.out.println(); } System.out.println(\n路径重建示例:); for (int i 0; i next.length; i) { for (int j 0; j next.length; j) { if (i ! j next[i][j] ! -1) { System.out.print(i - getPath(i, j, next) ); } } System.out.println(); } } private static String getPath(int i, int j, int[][] next) { if (next[i][j] -1) return 无路径; StringBuilder path new StringBuilder(); while (i ! j) { path.append(i).append(-); i next[i][j]; } path.append(j); return path.toString(); } public static void main(String[] args) { int[][] graph { {0, 5, INF, 10}, {INF, 0, 3, INF}, {5, INF, 0, 1}, {INF, INF, 4, 0} }; floyd(graph); } }代码中的几个精妙设计路径重建矩阵next[i][j]记录从i到j的最短路径上i的后继节点INF处理用Integer.MAX_VALUE表示∞输出时转换为∞提高可读性提前终止当发现dist[i][k]或dist[k][j]为∞时跳过计算4. 算法对比与工程实践建议在实际应用中Floyd算法并非总是最佳选择。下面是与Dijkstra算法的详细对比特性Floyd-WarshallDijkstra问题类型多源最短路径单源最短路径时间复杂度O(V³)O(E VlogV) with Fibonacci堆空间复杂度O(V²)O(V)负权边处理可以无负权回路不可以适用图规模小规模稠密图V500大规模稀疏图并行化潜力低三层循环强依赖中可并行处理顶点工程实践中的选择建议当需要频繁查询任意两点间最短路径时如导航系统的距离矩阵适合预处理Floyd结果对于社交网络中的好友推荐路径等稀疏图场景更适合多次Dijkstra计算在存在负权边但无负权回路的场景如金融套利检测Floyd是少数可选算法之一一个常见的优化技巧是提前终止当检测到对角线元素出现负数时存在负权回路立即终止算法// 在k循环结束后添加负权回路检测 for (int i 0; i n; i) { if (dist[i][i] 0) { throw new RuntimeException(图中存在负权回路); } }5. 常见面试问题深度解析面试中关于Floyd算法的问题通常分为三类以下是应对策略Q1为什么三重循环的顺序是k、i、j能改变吗这是动态规划的无后效性要求。k必须在外层因为算法是基于允许前k个顶点作为中转的阶段思想i和j的顺序理论上可以交换但不改变时间复杂度Q2如何处理路径输出而不仅是距离如示例代码所示维护next[i][j]矩阵重建路径时沿着next指针回溯时间复杂度O(L)L为路径长度Q3算法在稀疏图上的优化空间对于稀疏图可以先检查dist[i][k]是否为∞如果是则跳过内层循环使用邻接表存储时可以预先记录每个顶点的入边和出边减少不必要的判断// 稀疏图优化示例 for (int k 0; k n; k) { for (int i : inEdges[k]) { // 只遍历指向k的顶点 if (dist[i][k] INF) continue; for (int j : outEdges[k]) { // 只遍历从k出发的顶点 if (dist[k][j] ! INF dist[i][k] dist[k][j] dist[i][j]) { dist[i][j] dist[i][k] dist[k][j]; } } } }在准备面试时建议在白板上手写算法核心部分并强调三个要点动态规划思想的运用最优子结构、无后效性三重循环的物理意义逐步开放中转站与Dijkstra的本质区别多源vs单源负权处理理解Floyd算法的过程就像解开一个精巧的魔术——最初看似神秘的三重循环在明白动态规划的舞台机关后突然变得清晰而美妙。当我用那张逐步更新的矩阵图向面试官展示算法如何学习到更短路径时看到的正是技术交流中最珍贵的啊哈时刻。

相关文章:

面试官问我Floyd算法,我画了张图就讲明白了(附Java代码实现)

用一张图讲透Floyd算法:从三重循环到动态规划的精妙拆解 面试官推了推眼镜,在白板上画出一个带权图:"能解释下Floyd算法如何计算任意两点间最短路径吗?"作为过来人,我深知这是考察动态规划思想的经典问题。不…...

如何用genshin-wish-export快速导出原神抽卡记录:完整免费指南

如何用genshin-wish-export快速导出原神抽卡记录:完整免费指南 【免费下载链接】genshin-wish-export Easily export the Genshin Impact wish record. 项目地址: https://gitcode.com/GitHub_Trending/ge/genshin-wish-export 你是否曾为原神抽卡记录无法导…...

音频放大器电阻选择指南

在音频放大器的设计中,电阻看似是最基础、最不起眼的元件,却是决定音质纯净度、增益精准度、声道平衡度与系统稳定性的核心基石。从微弱的前级信号放大,到强大的末级功率输出,每一颗电阻的参数选择都直接影响声音的细节解析力、底…...

Java程序员转大模型开发:从入门到落地,小白也能轻松上手

在AI技术飞速迭代、大模型从实验室走向产业落地的今天,传统编程领域的Java程序员正面临着新的职业选择——转型大模型开发。这不仅是一场跨越技术边界的挑战,更是一次实现职业升级、突破薪资瓶颈的绝佳机遇。相比于陷入传统开发的内卷,借助大…...

MoviePilot:打造终极NAS媒体库自动化管理神器

MoviePilot:打造终极NAS媒体库自动化管理神器 【免费下载链接】MoviePilot NAS媒体库自动化管理工具 项目地址: https://gitcode.com/gh_mirrors/mo/MoviePilot MoviePilot是一个开源NAS媒体库自动化管理工具,专为电影爱好者设计,提供…...

RealSense D435数据后处理指南:从rosbag到图片/视频的三种实用方法对比

RealSense D435数据后处理实战:三种rosbag转图片/视频方案深度评测 当你手握RealSense D435采集的rosbag数据时,是否曾为如何高效提取关键帧而头疼?作为计算机视觉和机器人领域的常用传感器,D435采集的RGB-D数据往往需要经过后处理…...

国风美学生成模型v1.0在嵌入式设备上的部署探索与性能分析

国风美学生成模型v1.0在嵌入式设备上的部署探索与性能分析 最近,一个挺有意思的想法在我脑子里转悠:那些能生成精美国风画作的AI模型,能不能塞进一个小小的嵌入式设备里,让它随时随地都能创作?比如,一个智…...

开源规则引擎选型指南:从轻量级到企业级的实战对比

1. 规则引擎入门:为什么你的项目需要它? 第一次接触规则引擎这个概念是在2015年,当时我在开发一个电商促销系统。每当运营同学提出"满300减50"、"会员日双倍积分"这类需求时,我们都要紧急修改代码、测试、上线…...

药品名称全解析:从通用名到商品名的数据库高效查询指南

1. 药品名称的三大核心分类:从化学结构到品牌营销 第一次接触药品名称时,很多人都会被各种术语绕晕。我刚开始做医药数据分析时,就曾经把某款降压药的化学名和商品名搞混,差点闹出大乌龙。其实药品命名就像人的身份证系统&#xf…...

MusicFreePlugins终极指南:免费打造你的全能音乐播放中心

MusicFreePlugins终极指南:免费打造你的全能音乐播放中心 【免费下载链接】MusicFreePlugins MusicFree播放插件 项目地址: https://gitcode.com/gh_mirrors/mu/MusicFreePlugins 你是否厌倦了在不同音乐平台间频繁切换?是否因为版权限制而无法听…...

新版Simulink中Signal Builder被Signal Editor替代的解决方案

1. 为什么Signal Builder会被Signal Editor取代? 如果你最近升级了MATLAB/Simulink,可能会发现一个令人困惑的现象:熟悉的Signal Builder模块不见了。这可不是软件bug,而是MathWorks官方有计划的替代方案。作为一个从2012版就开始…...

保姆级教程:在MMSegmentation框架下复现HRNetV2+OCR语义分割(附完整代码与调试技巧)

从零实现HRNetV2OCR语义分割:MMSegmentation实战指南与深度调优 当你在GitHub上搜索"HRNetV2 OCR implementation"时,会发现大多数仓库要么只有论文复现的片段代码,要么存在各种环境兼容性问题。作为计算机视觉领域经典的语义分割方…...

【PyTorch】深入解析Tensor布尔值歧义问题及高效解决方案

1. 为什么PyTorch会报"布尔值歧义"错误? 第一次在PyTorch中看到"Boolean value of Tensor with more than one value is ambiguous"这个报错时,我正熬夜调试一个图像分类模型。当时用if语句直接判断一个特征张量,程序突然…...

从零到一:在Ubuntu上部署GTSAM因子图工具箱的完整指南

1. 环境准备:打造GTSAM的温床 第一次接触GTSAM时,我像大多数开发者一样被各种依赖项搞得晕头转向。后来发现,只要把基础环境搭好,后续的安装就像搭积木一样顺理成章。这里我推荐使用Ubuntu 20.04 LTS版本,不仅因为它的…...

告别手机小屏幕:3个理由让你在电脑上体验酷安社区

告别手机小屏幕:3个理由让你在电脑上体验酷安社区 【免费下载链接】Coolapk-UWP 一个基于 UWP 平台的第三方酷安客户端 项目地址: https://gitcode.com/gh_mirrors/co/Coolapk-UWP 你是否曾经在手机上刷酷安时,觉得屏幕太小、操作不便&#xff1f…...

AI工程师的进化

引言:AI时代对工程师能力的重构传统工程师技能模型与AI时代的对比超级能力(Superpowers)的定义:技术深度、跨界融合、人机协作核心能力维度进化技术栈的量子跃迁从单一编程语言到全栈AI化:MLOps、AutoML工具的掌握低代…...

告别抖动与失步!用AccelStepper库为ESP32-S3步进电机实现丝滑梯形加减速

告别抖动与失步!用AccelStepper库为ESP32-S3步进电机实现丝滑梯形加减速 在3D打印机、CNC雕刻机或机器人关节控制项目中,步进电机的运动平稳性直接决定最终成品的质量。许多开发者在使用ESP32-S3驱动步进电机时,常会遇到启动时的机械抖动、高…...

Unity游戏模组加载终极指南:MelonLoader完整使用教程

Unity游戏模组加载终极指南:MelonLoader完整使用教程 【免费下载链接】MelonLoader The Worlds First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono 项目地址: https://gitcode.com/gh_mirrors/me/MelonLoader 想要为心爱的U…...

别再到处找安装包了!手把手教你从ST官网正确下载STM32CubeMX任意历史版本

从ST官网精准获取STM32CubeMX历史版本的完整指南 作为嵌入式开发者,我们经常需要回退到某个特定的STM32CubeMX版本来兼容旧项目。你可能遇到过这样的困境:官网只提供最新版本下载,而网盘资源又存在安全风险。本文将彻底解决这个痛点&#xff…...

新手接入 CDN 必踩的 8 个坑,一次讲清解决办法

作为刚接触CDN的运维新手,前段时间帮公司网站接入CDN,踩了一堆五花八门的坑——从配置报错到加速失效,甚至差点搞崩源站,折腾了快一周才彻底理顺。结合自身实操经验,整理了新手接入CDN最易踩的8个高频坑,每…...

智能项目员中的进度控制与资源协调

智能项目员中的进度控制与资源协调 在当今快速发展的数字化时代,智能项目员已成为企业项目管理中不可或缺的角色。他们不仅需要掌握传统项目管理的核心技能,还需借助智能化工具实现高效的进度控制与资源协调。如何通过技术手段优化项目流程、避免资源浪…...

patch-package 打补丁方案详解

patch-package 打补丁方案详解 背景 在日常开发中,我们经常会遇到这样的场景: 使用了一个 npm 包,但它有个bug社区的修复还没发布又不想等待官方更新或者这个包已经无人维护了 这时候,patch-package 就是你的解决方案。它可以让你…...

简站WordPress主题下载与安装完全指南

“简站WordPress主题”是一套专注于国内企业展示型网站的WordPress主题系列,以其轻量、简洁、SEO友好著称。为了确保您获得安全、完整、可长期使用的主题文件,并避免因使用盗版主题带来的安全风险与法律问题,请严格按照以下官方渠道进行下载。…...

自动化测试创新

自动化测试创新:提升效率与质量的新引擎 在数字化转型的浪潮中,软件开发的迭代速度不断加快,传统手工测试已难以满足高效、精准的需求。自动化测试通过技术创新,正成为企业降本增效的核心工具。它不仅能够缩短测试周期&#xff0…...

AI智能证件照工坊值得部署吗?隐私安全+离线运行实测分析

AI智能证件照工坊值得部署吗?隐私安全离线运行实测分析 1. 这不是P图工具,而是一台“证件照打印机” 你有没有过这样的经历:临时要交简历,发现手机里没有合规的证件照;赶着办护照,照相馆排队两小时&#…...

告别BiocManager安装卡顿:用conda/mamba一键部署R的clusterProfiler生信分析环境

告别BiocManager安装卡顿:用conda/mamba一键部署R的clusterProfiler生信分析环境 在生物信息学分析中,富集分析是不可或缺的一环,而clusterProfiler作为GO和KEGG功能富集分析的核心工具包,其重要性不言而喻。然而,许多…...

别再折腾第三方插件了!手把手教你用Abaqus 2021官方接口关联Solidworks 2022

告别插件依赖:Abaqus与Solidworks官方关联方案全解析 在工程仿真领域,Abaqus和Solidworks的组合堪称黄金搭档——前者以强大的CAE分析能力著称,后者则是三维建模的行业标杆。然而,这对黄金组合的协作过程却常常让工程师们头疼不已…...

一键开启二次元世界:梦幻动漫魔法工坊快速上手实战体验

一键开启二次元世界:梦幻动漫魔法工坊快速上手实战体验 1. 走进梦幻动漫魔法工坊 想象一下,你只需要输入一段文字描述,就能立即获得一张精美的动漫风格图片——这就是梦幻动漫魔法工坊带给你的魔法体验。这个基于Diffusion模型和LoRA微调技…...

STEP3-VL-10B部署教程:CSDN算力平台一键拉起WebUI,7860端口快速访问指南

STEP3-VL-10B部署教程:CSDN算力平台一键拉起WebUI,7860端口快速访问指南 1. 开篇:为什么你需要关注STEP3-VL-10B? 如果你正在寻找一个既强大又轻便的多模态AI模型,那么STEP3-VL-10B绝对值得你花10分钟了解一下。 想…...

终极AMD Ryzen优化指南:SMUDebugTool让你的电脑性能飙升![特殊字符]

终极AMD Ryzen优化指南:SMUDebugTool让你的电脑性能飙升!🚀 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Ta…...