【LeetCode每日一题】【BFS模版与例题】863.二叉树中所有距离为 K 的结点
BFS的基本概念
BFS 是广度优先搜索(Breadth-First Search)的缩写,是一种图遍历算法。它从给定的起始节点开始,逐层遍历图中的节点,直到遍历到目标节点或者遍历完所有可达节点。
BFS 算法的核心思想是先访问当前节点的所有邻居节点,然后再访问邻居节点的邻居节点,依此类推,直到遍历完整个图。
BFS 模版
BFS 使用队列(Queue)数据结构来辅助实现,它按照先进先出(FIFO)的顺序管理待访问的节点。用**集合(Set)**来辅助节点是否已经被访问,算法的基本流程如下:
- 将起始节点放入队列中,并标记为已访问。
- 从队列中取出一个节点,访问该节点,判断该节点是否符合条件。
- 将该节点的所有未访问过的邻居节点加入队列,并标记为已访问。
- 重复步骤 2 和步骤 3,直到队列为空。
模版1:不必记录深度
function BFS(start, target) {const queue = []; // 核心数据结构const visited = new Set(); // 避免走回头路// 将起始节点放入队列中,并标记为已访问。queue.push(start); visited.add(start);while (queue.length > 0) {const sz = queue.length;const cur = queue.shift();/* 划重点:这里判断是否到达终点 */if (cur === target)return step;/* 将 cur 的所有未访问过的邻居节点加入队列,并标记为已访问。 */for (const x of cur.adj()) {if (!visited.has(x)) {queue.push(x);visited.add(x);}}}
}
模版2:需要记录深度的
function BFS(start, target) {const queue = []; // 核心数据结构const visited = new Set(); // 避免走回头路// 将起始节点放入队列中,并标记为已访问。queue.push(start); visited.add(start);let step = 0; // 记录扩散的步数while (queue.length > 0) {const sz = queue.length;/* 将当前队列中的所有节点向四周扩散 */for (let i = 0; i < sz; i++) {const cur = queue.shift();/* 划重点:这里判断是否到达终点 */if (cur === target)return step;/* 将 cur 的所有未访问过的邻居节点加入队列,并标记为已访问。 */for (const x of cur.adj()) {if (!visited.has(x)) {queue.push(x);visited.add(x);}}}/* 划重点:更新步数在这里 */step++;}
}
BFS 算法通常用于以下场景:
- 寻找两个节点之间的最短路径。
- 在树或图中寻找特定深度或层级的节点。
- 检查图是否是连通的。
- 拓扑排序。
- 解决迷宫问题等。
例题
111 二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
var minDepth = function(root) {if(root === null){return 0;}// 记录深度let step = 0;// BFS关键数据结构let queue = [];let visited = new Set();queue.push(root);visited.add(root);while(queue.length > 0){let size = queue.length;for(let i = 0;i<size;i++){/* 划重点:这里判断是否到达终点 */let node = queue.shift();if(node.left === null && node.right === null){return step+1;}/* 将 cur 的所有未访问过的邻居节点加入队列,并标记为已访问。 */if(node.left !== null && !visited.has(node.left)){queue.push(node.left);visited.add(node.left);}if(node.right !== null && !visited.has(node.right)){queue.push(node.right);visited.add(node.right);}}step++;}return step;
};
863.二叉树中所有距离为 K 的结点
给定一个二叉树(具有根结点 root), 一个目标结点 target ,和一个整数值 k 。
返回到目标结点 target 距离为 k 的所有结点的值的列表。 答案可以以 任何顺序 返回。
思路:
需要我们在树中寻找特定深度或层级的节点,但是又不是从根节点开始,因此需要我们将树 转化成 图。
可以通过哈希表和DFS将树转化成图
var distanceK = function(root, target, k) {// 起点是target,先通过哈希表+DFS将树转化成图const parents = getParents(root);// 结果数组let ans = []// BFS关键数据结构let queue = []const visited = new Set()queue.push(target);visited.add(target.val);// 记录深度let step = 0;while(queue.length){// 遍历每一层的节点const len = queue.length;for(let i = 0;i<len;i++){// 判断当前节点是否符合条件。const node = queue.shift();if(step === k){ans.push(node.val);}// 将相邻的节点都放入到if(node.left && !visited.has(node.left.val)){queue.push(node.left);visited.add(node.left.val);}if(node.right && !visited.has(node.right.val)){queue.push(node.right);visited.add(node.right.val);}if(parents.has(node.val) && !visited.has(parents.get(node.val).val)){queue.push(parents.get(node.val));visited.add(parents.get(node.val).val);}}// 遍历完一层后深度+1step++;}return ans;};function getParents(root) {const parents = new Map();const findParents = (root) => {if (root.left) {parents.set(root.left.val, root);findParents(root.left);}if (root.right) {parents.set(root.right.val, root);findParents(root.right);}};findParents(root);return parents;
}
相关文章:
【LeetCode每日一题】【BFS模版与例题】863.二叉树中所有距离为 K 的结点
BFS的基本概念 BFS 是广度优先搜索(Breadth-First Search)的缩写,是一种图遍历算法。它从给定的起始节点开始,逐层遍历图中的节点,直到遍历到目标节点或者遍历完所有可达节点。 BFS 算法的核心思想是先访问当前节点的…...

设计模式-结构模式-装饰模式
装饰模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。 //首先,定义一个组件接口: public in…...

MySQL:一行记录如何
1、表空间文件结构 表空间由段「segment」、区「extent」、页「page」、行「row」组成,InnoDB存储引擎的逻辑存储结构大致如下图: 行 数据库表中的记录都是按「行」进行存放的,每行记录根据不同的行格式,有不同的存储结构。 页…...

‘grafana.ini‘ is read only ‘defaults.ini‘ is read only
docker安装grafana 关闭匿名登录情况下的免密登录遇到问题 grafana.ini is read only defaults.ini is read only 参考回答(Grafana.ini giving me the creeps - #2 by bartweemaels - Configuration - Grafana Labs Community Forums) 正确启动脚本 …...

博途PLC 面向对象系列之“输送带控制功能块“(SCL代码)
这篇是面向对象系列之"输送带功能块"的封装,面向对象是系列文章,相关链接如下: 1、面向对象系列之找"对象" https://rxxw-control.blog.csdn.net/article/details/136150027https://rxxw-control.blog.csdn.net/article/details/1361500272、面向对象…...

2024-02学习笔记
1.当我们向Set集合中添加一个已经存在的元素时 当我们向Set集合中添加一个已经存在的元素时,Set集合会如何处理呢?实际上,Set集合不会将重复的元素添加到集合中。当我们向Set集合中添加一个元素时,Set集合会首先判断该元素是否已…...
最新消息:英特尔宣布成立全新独立运营的FPGA公司——Altera
今天,英特尔宣布成立全新独立运营的FPGA公司——Altera(2015年6月Intel以 167 亿美元的价格,收购FPGA厂商Altera)。首席执行官Sandra Rivera和首席运营官Shannon Poulin分享展示其在超过550亿美元的市场中保持领先性的战略规划&am…...

RC正弦波振荡电路
RC正弦波振荡电路 RC正弦波振荡电路又称文氏电桥振荡电路,可以设计频率为f1/2πRC的正弦波发生器。 RC正弦波振荡电路设计:50Hz,振幅为3.47V 电路分析: 1.起振条件取决于R1, R4,R2与1N4148并联电阻(下面简称Rf&#…...

【Git学习笔记】提交PR
step1 克隆一个仓库 git clone .....step2 创建一个分支 (Creating a branch) # 创建并切换到本地新分支,分支的命名尽量简洁,并与解决的问题相关 git checkout -b delete-unused-linkstep3 做出修改 (Make changes) step4 提交修改 # 保存本地修…...

线程池的相关参数
在Java中线程池是一种池化技术,用于管理和复用线程,提高线程的利用率和性能。下面是一些常见的线程池的参数及其解释: 一:线程池的七大参数 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTim…...

图书推荐||Word文稿之美
让你的文档从平凡到出众! 本书内容 《Word文稿之美》是一本全面介绍Word排版技巧和应用的实用指南。从初步认识数字排版到高效利用模板、图文配置和表格与图表的排版技巧,再到快速修正错误和保护文件,全面系统地讲解数字排版的技术和能力&…...

前端导出word文件的多种方式、前端导出excel文件
文章目录 纯前借助word模板端导出word文件 (推荐)使用模板导出 前端通过模板字符串导出word文件前端导出 excel文件,node-xlsx导出文件,行列合并 纯前借助word模板端导出word文件 (推荐) 先看效果…...

Linux和Windows操作系统在腾讯云幻兽帕鲁服务器上的内存占用情况如何?
Linux和Windows操作系统在腾讯云幻兽帕鲁服务器上的内存占用情况如何? 对于Linux操作系统,有用户分享了个人最佳实践来解决内存问题,包括使用Linux脚本让服务器每天重启一次,以及建议在不需要时尽量减少虚拟内存的使用。此外&…...

腾讯云4核8G的云服务器性能水平?使用场景说明
腾讯云4核8G服务器适合做什么?搭建网站博客、企业官网、小程序、小游戏后端服务器、电商应用、云盘和图床等均可以,腾讯云4核8G服务器可以选择轻量应用服务器4核8G12M或云服务器CVM,轻量服务器和标准型CVM服务器性能是差不多的,轻…...

1_SQL
文章目录 前端复习SQL数据库的分类关系型数据库非关系型数据库(NoSQL) 数据库的构成软件架构MySQL内部数据组织方式 SQL语言登录数据库数据库操作查看库创建库删除库修改库 数据库中表的操作选择数据库创建表删除表查看表修改表 数据库中数据的操作添加数…...

PoC免写攻略
在网络安全领域,PoC(Proof of Concept)起着重要的作用,并且在安全研究、漏洞发现和漏洞利用等方面具有重要的地位。攻击方视角下,常常需要围绕 PoC 做的大量的工作。常常需要从手动测试开始编写 PoC,再到实…...

c1-周考2
c1-第二周 9月-技能1.一个岛上有两种神奇动物,其中神奇鸟类2个头3只脚,神奇兽类3个头8只脚。游客在浓雾中看到一群动物,共看到35个头和110只脚,求可能的鸟类和兽类的只数2.构建一个长度为5的数组,并且实现下列要求3.构…...

express+mysql+vue,从零搭建一个商城管理系统7--文件上传,大文件分片上传
提示:学习express,搭建管理系统 文章目录 前言一、安装multer,fs-extra二、新建config/upload.js三、新建routes/upload.js四、修改routes下的index.js五、修改index.js六、新建上传文件test.html七、开启jwt验证token,通过login接…...

markdown的使用(Typora)
文章目录 markdown的使用(Typora)一.标题二.段落格式2.1 换行2.2 分割线2.3 字体2.4 上下标2.5 脚注2.6 改变字体颜色 三.列表3.1 无序列表3.2 有序列表3.3 列表嵌套3.4 任务列表 四.区块五.代码显示5.1 行内代码5.2 代码块 六.链接七.图片八.表格九.表情符号大纲十、流程图10.…...

【python】json转成成yaml中文编码异常显示成:\u5317\u4EAC\u8DEF123\u53F7
姊妹篇:【python】json转成成yaml json数据 {"name": "张三","age": 30,"isMarried": false,"children": [{"name": "小王","age": 5},{"name": "小李",&qu…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
shell脚本质数判断
shell脚本质数判断 shell输入一个正整数,判断是否为质数(素数)shell求1-100内的质数shell求给定数组输出其中的质数 shell输入一个正整数,判断是否为质数(素数) 思路: 1:1 2:1 2 3:1 2 3 4:1 2 3 4 5:1 2 3 4 5-------> 3:2 4:2 3 5:2 3…...