行业知识
【LeetCode每日一题】【BFS模版与例题】863.二叉树中所有距离为 K 的结点
2026-11-04 20:07:09
来源:互联网转载
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; iBFS 算法通常用于以下场景:
- 寻找两个节点之间的最短路径。
- 在树或图中寻找特定深度或层级的节点。
- 检查图是否是连通的。
- 拓扑排序。
- 解决迷宫问题等。
例题
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 /* 划重点:这里判断是否到达终点 */ 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;}; // 起点是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 // 判断当前节点是否符合条件。 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); } } // 遍历完一层后深度+1 step++; } 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;}