广度优先搜索算法 BFS 实战 All In One
Breadth-First Search / BFS
BFS / 广度优先搜索 / 广度优先遍历 / 按层次遍历树
demos
LeetCode
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2023-01-31
* @modified
*
* @description 2196. Create Binary Tree From Descriptions
* @description 2196. 根据描述创建二叉树
* @difficulty Medium
* @ime_complexity O(n)
* @space_complexity O(n)
* @augments
* @example
* @link https://leetcode.com/problems/create-binary-tree-from-descriptions/
* @link https://leetcode.cn/problems/create-binary-tree-from-descriptions/
* @solutions
*
* @best_solutions
*
*/
export {};
const log = console.log;
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = (val === undefined ? 0 : val);
this.left = (left === undefined ? null : left);
this.right = (right === undefined ? null : right);
}
}
// [parent, child, isLeft]
// isLefti == 1,true
// isLefti == 0, false
const findRoot = (nodes) => {
if(nodes.length === 1) {
return nodes[0][0];
} else {
const parents: number[] = [];
const childs: number[] = [];
// const parents = [];
// const childs = [];
for(let node of nodes) {
const [parent, child] = node;
parents.push(parent);
childs.push(child);
}
for(let node of nodes) {
const [parent, child] = node;
if(!childs.includes(parent)) {
return parent;
}
}
}
}
/*
findRoot([[20,15,1],[20,17,0],[50,20,1],[50,80,0],[80,19,1]])
// 50
findRoot([[1,2,1],[2,3,0],[3,4,1]]);
// 1
*/
/*
[[20,15,1],[20,17,0],[50,20,1],[50,80,0],[80,19,1]]
[50,20,80,15,17,19]
*/
// DFS 深度优先搜索 / 深度优先遍历
function dfs(root, nodes) {
const childs = nodes.filter(item => item[0] === root.val);
for(let node of childs) {
const [parent, child, isLeft] = node;
if(isLeft) {
root.left = new TreeNode(child);
dfs(root.left, nodes);
} else {
root.right = new TreeNode(child);
dfs(root.right, nodes);
}
}
}
function createBinaryTree(descriptions: number[][]): TreeNode | null {
const rootValue = findRoot(descriptions);
const root = new TreeNode(rootValue);
dfs(root, descriptions);
return root;
};
// 按层次遍历树,BFS 广度优先搜索/遍历
function bfs(root, arr) {
if(root === null) {
return;
}
// 去重
if(!arr.includes(root.val)) {
arr.push(root.val)
}
// 先同层遍历
if(root.left !== null && root.left.val) {
arr.push(root.left.val)
}
if(root.right !== null && root.right.val) {
arr.push(root.right.val)
}
// 后递归深度遍历
if(root.left !== null) {
bfs(root.left, arr)
}
if(root.right !== null) {
bfs(root.right, arr)
}
}
function getBinaryTreeValues(root: TreeNode | null) {
const arr = [];
// 按层次遍历树,BFS 广度优先搜索/遍历
bfs(root, arr);
return arr;
};
/*
Constraints:
1 <= descriptions.length <= 104
descriptions[i].length == 3
1 <= parenti, childi <= 105
0 <= isLefti <= 1
The binary tree described by descriptions is valid.
*/
// 测试用例 test cases
const testCases = [
{
input: [[20,15,1],[20,17,0],[50,20,1],[50,80,0],[80,19,1]],
result: [50,20,80,15,17,19],
desc: 'value equal to [50,20,80,15,17,19]',
},
{
input: [[1,2,1],[2,3,0],[3,4,1]],
result: [1,2,null,null,3,4],
desc: 'value equal to [1,2,null,null,3,4]',
},
];
for (const [i, testCase] of testCases.entries()) {
const result = createBinaryTree(testCase.input);
const values = getBinaryTreeValues(result);
const nums = testCase.result.filter(i => i !== null);
log(`values =`, values);
log(`nums =`, nums);
log(`test case ${i} result: `, JSON.stringify(values) === JSON.stringify(nums) ? `✅ passed` : `❌ failed`);
// log(`test case ${i} result: `, JSON.stringify(values) === JSON.stringify(nums) ? `✅ passed` : `❌ failed`, result);
}
/*
$ npx ts-node ./2196\ create-binary-tree-from-descriptions.ts
*/