文章简要概述
- 本文主要进行树相关的算法题刷题题解记录,记录树相关算法以及如何解。
- 这文一共有5道题,主要介绍leetcode中
968. 监控二叉树、662. 二叉树最大宽度、144. 二叉树的前序遍历、589. N 叉树的前序遍历、和226. 翻转二叉树的解题思路。
与树相关算法
968. 监控二叉树
题目大意:
给定一个二叉树,我们在树的节点上安装摄像头。
节点上的每个摄影头都可以监视**其父对象、自身及其直接子对象。**
计算监控树的所有节点所需的最小摄像头数量。
示例
输入: [0,0,null,0,0]
输出: 1
解释: 如图所示,一台摄像头足以监控所有节点。
解题思路:
- 如果在 root 处安放摄像头,则root的left,right 一定也会被监控到。此时,只需要保证left 的两棵子树被覆盖,同时保证 right 的两棵子树也被覆盖即可。
- 如果 root 处不安放摄像头,则除了覆盖 root 的两棵子树之外,孩子left,right 之一必须要安装摄像头,从而保证 root 会被监控到。 那么可以得到一下结论:
- 状态 a:root 必须放置摄像头的情况下,覆盖整棵树需要的摄像头数目。
- 状态 b:覆盖整棵树需要的摄像头数目,无论 root 是否放置摄像头。
- 状态 c:覆盖两棵子树需要的摄像头数目,无论节点 root 本身是否被监控到。
代码:
function minCameraCover (root) {
const dfs = (root) => {
if (!root) {
return [Math.floor(Number.MAX_SAFE_INTEGER / 2), 0, 0];
}
const [la, lb, lc] = dfs(root.left);
const [ra, rb, rc] = dfs(root.right);
const a = lc + rc + 1;
const b = Math.min(a, Math.min(la + rb, ra + lb));
const c = Math.min(a, lb + rb);
return [a, b, c];
}
return dfs(root)[1];
};
662. 二叉树最大宽度
题目大意:
给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空。
每一层的宽度被定义为两个端点(该层最左和最右的非空节点,两端点间的null节点也计入长度)之间的长度。
示例:
输入:
1 / \ 3 2 / \ \ 5 3 9输出: 4
解释: 最大值出现在树的第 3 层,宽度为 4 (5,3,null,9)。
解题思路:
- 按照深度优先的顺序,我们记录每个节点的 position 。对于每一个深度,第一个到达的位置会被记录在
max[dep]中。 - 然后对于每一个节点,它对应这一层的可能宽度是
pos - max[dep] + 1 - 将每一层这些可能的宽度去一个最大值就是答案。
代码:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
function widthOfBinaryTree (root) {
let max = [];
function dsf(root, dep, idx) {
if(!root) return;
max[dep] = (max[dep] || [idx, idx]);
max[dep][0] = Math.min(max[dep][0], idx)
max[dep][1] = Math.max(max[dep][1], idx)
dsf(root.left, dep + 1, (idx << 1) + 1);
dsf(root.right, dep + 1, (idx << 1) + 2);
}
dsf(root, 0, 0);
return max.reduce((max, [l, r]) => Math.max(max, r - l), 0) + 1;
};
144. 二叉树的前序遍历
题目大意:
给你二叉树的根节点 `root` ,返回它节点值的 **前序** **遍历。
示例:
输入: root = [1,null,2,3]
输出: [1,2,3]
解题思路:
- 按照根左右的顺序,递归即可。
代码:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
function preorder (root, arr) {
if (!root) return root;
arr.push(root.val);
preorder(root.left, arr);
preorder(root.right, arr);
}
var preorderTraversal = function(root) {
const arr = [];
preorder(root, arr);
return arr;
};
589. N 叉树的前序遍历
题目大意:
给定一个 N 叉树,返回其节点值的 前序遍历 。
N 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)。
进阶:
递归法很简单,你可以使用迭代法完成此题吗?
示例:
输入: root = [1,null,3,2,4,null,5,6]
输出: [1,3,5,6,2,4]
解题思路:
- 采用栈的方式,将每一层的值放入栈中,为了保持从左到右的顺序,我们对应每一层的children的值先反转顺序。 -然后从栈顶取元素,这样递归操作。
代码:
/**
* // Definition for a Node.
* function Node(val, children) {
* this.val = val;
* this.children = children;
* };
*/
/**
* @param {Node|null} root
* @return {number[]}
*/
function preorder (root) {
if (!root) return [];
const res = [];
const cur = [];
cur.push(root);
while(cur.length) {
const node = cur.pop();
res.push(node.val);
node.children.reverse();
for(k in node.children) {
cur.push(node.children[k])
}
}
return res;
};
226. 翻转二叉树
题目大意:
翻转一棵二叉树。
示例:
输入:
4 / \ 2 7 / \ / \ 1 3 6 9输出:
4 / \ 7 2 / \ / \ 9 6 3 1
解题思路:
- 获取当前节点的左右子节点的内容,将左右子节的内容先反转
- 然后将反转后的左右子节点与根节点的左右子节点进行交换
- 递归以上操作
代码:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var invertTree = function(root) {
if (!root) return null;
const left = invertTree(root.left);
const right = invertTree(root.right);
root.left = right;
root.right = left;
return root;
};
结束语
数据结构与算法相关的练习题会持续输出,一起来学习,持续关注。当前是树部分。后期还会有其他类型的数据结构,题目来源于leetcode。往期文章:
树形结构-对应算法详解一 链表相关算法复习一 链表相关算法复习二
链表相关算法复习三 数据结构与算法-栈一 数据结构与算法-栈二
数据结构与算法-队列一 数据结构与算法-队列二 数据结构与算法-链表一
有兴趣的可以一起来刷题,如果文章对你有帮助,感谢点赞👍,关注!