【算法】【优选算法】多源BFS

【算法】【优选算法】多源BFS

目录

一、多源BFS

单源最短路:只有一个起点到终点的最短路问题。
多源最短路问题:有多个起点到终点的最短路问题。
多源BFS:用BFS来解决边权相同的多源最短路问题。

解法:

  1. 暴力解题,把多源最短路问题,转化为若干个单源最短路问题。
  2. 把所有起点当成一个起点,问题就变成了单源最短路问题。

二、542.01 矩阵

题目链接:542.01 矩阵

题目描述:

题目解析:

  • 给一个只有0 1 的二维数组,计算其中每一个元素到0的最短距离,自己是0距离就是0,将距离存入一个相同规模二维数组的下标中。

法一:
解题思路:

  • 我们如果遍历数组,找到1后,就进行求该元素到0的最短距离。
  • 求最短距离就使用前面求权值相同的最短距离的方法即可。
  • 但是会超时。
    解题代码:
//时间复杂度:O(M*N*M*N)//空间复杂度:O(M*N)classSolution{int[] dx ={0,0,1,-1};int[] dy ={1,-1,0,0};int m,n;publicint[][]updateMatrix(int[][] mat){ m = mat.length; n = mat[0].length;int[][] ret =newint[m][n];//遍历mat,遍历到1找最近的0,for(int i =0; i < m; i++){for(int j =0; j < n; j++){if(0== mat[i][j]){ ret[i][j]=0;}else{ ret[i][j]=bfs(mat,i,j);}}}return ret;}publicintbfs(int[][] mat,int x,int y){Queue<int[]> queue =newLinkedList<>(); queue.add(newint[]{x,y});boolean[][] flag =newboolean[m][n]; flag[x][y]=true;int ret =0;while(!queue.isEmpty()){ ret++;int size = queue.size();while(size--!=0){int[] arr = queue.poll();for(int i =0; i <4; i++){int a = arr[0]+ dx[i];int b = arr[1]+ dy[i];//入队if(a >=0&& a < m && b >=0&& b < n &&!flag[a][b]&& mat[a][b]!=0){ flag[a][b]=true; queue.add(newint[]{a,b});}//结束条件if(a >=0&& a < m && b >=0&& b < n && mat[a][b]==0)return ret;}}}return0;}}

法二:
解题思路:

  • 我们先将数组中的所有0下标,记录下来放入队列中。
  • 然后我们层序遍历,每一次循环遍历完当前队列中的值,往外BFS寻找没被标记的1,寻找的循环次数就是这个1的最短距离。

解题代码:

//时间复杂度:O(M*N)//空间复杂度:O(M*N)classSolution{int[] dx ={0,0,1,-1};int[] dy ={1,-1,0,0};publicint[][]updateMatrix(int[][] mat){int m = mat.length;int n = mat[0].length;int[][] ret =newint[m][n];boolean[][] flag =newboolean[m][n];Queue<int[]> queue =newLinkedList<>();//遍历mat,先把0全部放入队列,for(int i =0; i < m; i++){for(int j =0; j < n; j++){if(0== mat[i][j]){ queue.add(newint[]{i,j}); ret[i][j]=0;}}}//遍历队列中的元素,层序递进int tep =0;while(!queue.isEmpty()){ tep++;int size = queue.size();while(size--!=0){int[] arr = queue.poll();for(int i =0; i <4; i++){int x = arr[0]+ dx[i];int y = arr[1]+ dy[i];//入队if( x >=0&& x < m && y >=0&& y < n &&1== mat[x][y]&&!flag[x][y]){ flag[x][y]=true; queue.add(newint[]{x,y}); ret[x][y]= tep;}}}}return ret;}}

改进:

  • 我们就可以直接使用结果数组,来达到上面的flag数组的记录功能,也不再需要记录层数。
  • 我们将mat数组中元素为1对应的ret结果数组元素记录为-1;
  • 当我们BFS的时候,如果ret元素为-1,那么证明没有记录过,那么这个元素值就是出队列元素对应的ret值加一;
  • 当ret中数组元素没有-1了就会结束。
//时间复杂度:O(M*N)//空间复杂度:O(M*N)classSolution{int[] dx =newint[]{0,0,1,-1};int[] dy =newint[]{1,-1,0,0};publicint[][]updateMatrix(int[][] mat){int m = mat.length;int n = mat[0].length;int[][] ret =newint[m][n];Queue<int[]> queue =newLinkedList<>();for(int i =0; i < m; i++){for(int j =0; j < n; j++){ ret[i][j]=-1;if(mat[i][j]==0){ queue.add(newint[]{i,j}); ret[i][j]=0;}}}while(!queue.isEmpty()){int[] arr = queue.poll();for(int i =0; i <4; i++){int x = arr[0]+ dx[i];int y = arr[1]+ dy[i];//入队if(x >=0&& x < m && y >=0&& y < n && ret[x][y]==-1){ queue.add(newint[]{x,y}); ret[x][y]= ret[arr[0]][arr[1]]+1;}}}return ret;}}

三、1020.⻜地的数量

题目链接:1020.⻜地的数量

题目描述:

题目解析:

  • 给我们一个只有0 1 的数组,让我们统计(上下左右)连成块的1,并且这其中1没有在数组边的个数。

解题思路:

  • 我们使用标记数组标记 0 和 处于边上的 1
  • 将边上 1 的坐标放入队列
  • 在对队列中的元素实行BFS,入队条件是没被标记的元素。
  • 执行完BFS,就只会有符合条件的1 没有被标记。
  • 我们使用数组元素个数作为返回值,标记一次返回值就减1,最后就是所求值。

解题代码:

//时间复杂度:O(M*N)//空间复杂度:O(M*N)classSolution{int[] dx =newint[]{0,0,1,-1};int[] dy =newint[]{1,-1,0,0};publicintnumEnclaves(int[][] grid){int m = grid.length;int n = grid[0].length;Queue<int[]> queue =newLinkedList<>();boolean[][] flag =newboolean[m][n];//先将所有边界1入队并标记,将0标记int ret = m * n;for(int i =0; i < m; i++){for(int j =0; j < n; j++){if(grid[i][j]==1&&(i ==0|| i == m -1|| j ==0|| j == n -1)){ queue.add(newint[]{i,j}); flag[i][j]=true; ret--;}elseif(grid[i][j]==0){ flag[i][j]=true; ret--;}}}while(!queue.isEmpty()){int[] arr = queue.poll();for(int i =0; i <4; i++){int x = arr[0]+ dx[i];int y = arr[1]+ dy[i];if(x >=0&& x < m && y >=0&& y < n &&!flag[x][y]){ ret--; queue.add(newint[]{x,y}); flag[x][y]=true;}}}return ret;}}

四、1765. 地图中的最⾼点

题目链接:1765. 地图中的最⾼点

题目描述:

题目解析:

  • 给我们一个数组,其中1代表水域,0代表陆地。
  • 要求返回一个height高度数组,数组元素比上下左右元素高度差不超过一。返回能使height元素达到最大值的结果。

解题思路:

  • 我们先将水域入队,然后从水域元素往外扩,将四周元素入队,并且使其height值比让他入队的元素大1
  • 每个元素只能入一次对列,我们要有标技数组,我们可以直接使用height为标记数组,初始化时将陆地元素赋值-1,只要是值不是-1的元素就证明入过对列了。

解题代码:

//时间复杂度:O(M*N)//空间复杂度:O(M*N)classSolution{int[] dx =newint[]{0,0,1,-1};int[] dy =newint[]{1,-1,0,0};publicint[][]highestPeak(int[][] isWater){int m = isWater.length;int n = isWater[0].length;int[][] height =newint[m][n];Queue<int[]> queue =newLinkedList<>();//遍历isWater数组,1水域对应height为0,并入对,其余为-1,起标记作用for(int i =0; i < m; i++){for(int j =0; j < n; j++){ height[i][j]=-1;if(isWater[i][j]==1){ height[i][j]=0; queue.add(newint[]{i,j});}}}//BFSwhile(!queue.isEmpty()){int[] arr = queue.poll();for(int i =0; i <4; i++){int x = arr[0]+ dx[i];int y = arr[1]+ dy[i];//height为-1入队,值为出队列元素加1if(x >=0&& x < m && y >=0&& y < n && height[x][y]==-1){ height[x][y]= height[arr[0]][arr[1]]+1; queue.add(newint[]{x,y});}}}return height;}}

五、1162. 地图分析

题目链接:1162. 地图分析

题目描述:

题目解析:

  • 给我们一个grid数组,只有0 1
  • 找出 0 通过上下左右走到最近的1 的距离的最大值

解题思路:

  • 一个最经典的多源BFS
  • 我们从1开始走(将1全部入队),每走一次(将当前队列元素出完,将元素上下左右的没标记过的0入队),直到走完所有元素,最后走的次数就是结果。
    解题代码:
//时间复杂度:O(M*N)//空间复杂度:O(M*N)classSolution{int[] dx =newint[]{0,0,1,-1};int[] dy =newint[]{1,-1,0,0};publicintmaxDistance(int[][] grid){int m = grid.length;int n = grid[0].length;int ret =0;Queue<int[]> queue =newLinkedList<>();boolean[][] flag =newboolean[m][n];//所有1入队for(int i =0; i < m; i++){for(int j =0; j < n; j++){if(grid[i][j]==1){ queue.add(newint[]{i,j}); flag[i][j]=true; ret++;}}}//判断是否全0或全1if(ret ==0|| ret == m * n)return-1; ret =-1;//BFSwhile(!queue.isEmpty()){int size = queue.size(); ret++;while(size--!=0){int[] arr = queue.poll();for(int i =0; i <4; i++){int x = arr[0]+ dx[i];int y = arr[1]+ dy[i];//入队if(x >=0&& x < m && y >=0&& y < n &&!flag[x][y]&& grid[x][y]==0){ queue.add(newint[]{x,y}); flag[x][y]=true;}}}}return ret;}}

Read more

机器人 - 关于MIT电机模式控制

目录 一、MIT电机模式简单介绍 1.1 简单介绍 1.2 MIT模式的控制参数 1.3 使用场景 二、调试时建议 2.1 调试 2.2 问题定位 一、MIT电机模式简单介绍 1.1 简单介绍 Mixed Integrated Torque为一种混合控制模式,在同一帧CAN数据里包含 位置、速度、扭矩三类的闭环指令。驱动器里面把位置环、速度环、前馈扭矩相加,得到一个参考电流,然后再交给电流环完成精准扭矩输出。 1.2 MIT模式的控制参数 参数含义取值范围(常见)说明kp位置比例系数(刚度)0 ~ 500 (单位视驱动器而定)kp = 0 时位置环失效,

By Ne0inhk
低代码结合大模型:中小企业半天构建专属SaaS应用的完整路径

低代码结合大模型:中小企业半天构建专属SaaS应用的完整路径

👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕AI这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获! 文章目录 * 低代码结合大模型:中小企业半天构建专属SaaS应用的完整路径 😊 * 低代码与大模型:强强联合 💪 * 半天构建SaaS应用的路径 🛠️ * 阶段1: 需求分析与规划(1小时) 📋 * 阶段2: 平台设置与环境配置(1小时) ⚙️ * 阶段3: 应用开发与智能集成(2小时) 🎨 * 阶段4: 测试与部署(2小时) 🚀 * 最佳实践与注意事项 ⚠️ * 结语 🌟 低代码结合大模型:中小企业半天构建专属SaaS应用的完整路径 😊 在当今数字化浪潮中,中小企业往往面临资源有限、技术门槛高的挑战,难以快速构建定制化的SaaS(软件即服务)应用。然而,随着低代码平台和大型语言模型(LLM)的融合,这一局面正在改变。通过

By Ne0inhk
Nano Banana进行AI绘画中文总是糊?一招可重新渲染,清晰到可直接汇报

Nano Banana进行AI绘画中文总是糊?一招可重新渲染,清晰到可直接汇报

文章目录 * 1. 为什么 Nano Banana 生成的中文经常不清晰? * 2. 解决思路:Nano Banana + Seedream 4.5 的两段式工作流 * 3. 实战:先用 Nano Banana 生成架构图(中文会糊) * 4. 部署 Personal LLM API,并配置 Seedream 4.5 * 5. 用 Cherry Studio 配置已部署的 LLM 接口 * 6. 关键一步:用 Seedream 4.5 对“中文文字重新渲染” * 7. 效果对比:字清晰、无错位、图形保持不变

By Ne0inhk
DAY4 基于 OpenClaw + 飞书开放平台实现 AI 新闻推送机器人

DAY4 基于 OpenClaw + 飞书开放平台实现 AI 新闻推送机器人

DAY4 基于 OpenClaw + 飞书开放平台实现 AI 新闻推送机器人 目录 DAY4 基于 OpenClaw + 飞书开放平台实现 AI 新闻推送机器人 前  言 1 环境准备 1.1 华为云开发环境 1.2 ModelArts 代金券与模型服务 1.3 启动 OpenClaw 网关 2 飞书开放平台配置 2.1 创建企业自建应用 2.2 添加机器人能力 2.3 配置应用权限 2.4 发布应用版本 3 OpenClaw 与飞书集成 3.1 配置 OpenClaw

By Ne0inhk