最大距离二叉树节点
来源:互联网 发布:windows 10可以投屏吗 编辑:程序博客网 时间:2024/05/16 08:58
题目
给定一个二叉树,定义两个节点的距离为这两个节点之间所有边的个数,要求这个二叉树中两个节点之间的最大距离。例如下图,两个节点之间的最大距离是5。
分析1
对于树中任何一个节点,包括该节点的树及其所有子树中存在的最大距离可以通过三种途径得到:
- 在该节点的左子树中;
- 在该节点的右子树中;
- 将该节点作为根,横跨左右子树,最大距离是该节点左子树最大深度,加上右子树最大深度,再加2。
这样很容易写出递归形式的实现,其中还需要计算的是该节点的最大深度,这同样可以利用递归实现。需要注意的是,在递归实现最大深度时,遍历到叶子节点的null
节点后应该返回-1,这样叶子节点的深度才为0;而递归实现最大距离时,遍历到叶子节点的null
节点后应该返回0,表示没有子树的叶子节点与它自身的距离为0。
代码1
public class BTDistance { static class Node { Node left, right; } static int maxDist(Node root) { if (root == null) return 0; // 当前最大距离存在于左右子树中 int maxDis = Math.max(maxDist(root.left), maxDist(root.right)); // 或者跨越了根节点 maxDis = Math.max(maxDis, maxDepth(root.left) + maxDepth(root.right) + 2); return maxDis; } static int maxDepth(Node root) { if (root == null) return -1; int lDepth = maxDepth(root.left);// 左子树最大深度 int rDepth = maxDepth(root.right);// 右子树最大深度 return Math.max(lDepth, rDepth) + 1;// 当前最大深度是左右子树最大深度加1 }}
分析2
简单的递归实现总是由于很多的重复计算而效率低下。对于上述实现,求每个节点的最大距离时都会将它的所有子树节点的最大距离重复计算一遍,并且求每个节点的最大深度时也会将它的所有子树节点的最大深度重复计算一遍。那么有什么好的改进方法呢?
在《算法导论》中我们见到过动态规划的自顶向下实现方法,其关键是加入了备忘机制,即在递归过程中维护一个全局性的表,它保存已经计算过的子问题的结果,对于在解决上层子问题中遇到的相同子问题直接查表即可,从而减少了重复的计算。那么这种方法能否应用到本题中呢?
首先考察这个问题是否能用动态规划来实现。对于所遍历到的任何一个节点,其具有的最大距离只需要在包含该节点的树及其所有子树中寻找,即满足动态规划的无后效性。对于一个节点
其次考虑如何加入备忘机制。我们需要保存的中间结果有两个,即Memo
类,且和节点类一样包含左右子树指针,然后按照原二叉树构造一个结构完全一样的Memo
为节点的二叉树,于是在原二叉树的递归轨迹就可以同样应用于这个Memo
二叉树并更新其中的域。
再仔细分析可以发现,对于节点Memo
类只需要在当前递归层创建即可,它的左右子树的Memo
类对它进行更新后直接丢弃,最后返回Memo
类到上一递归层即可。从而Memo
类并不需要具有树形结构,减少了存储空间。
代码2
public class BTDistance { static class Node { Node left, right; } static class Memo { int maxDepth, maxDist; Memo(int depth, int dis) { this.maxDepth = depth;// 该节点左右子树中的最大深度 this.maxDist = dis;// 包括该节点的树及其所有子树中的最大距离 } } static Memo maxDist(Node root) { if (root == null) { return new Memo(-1, 0); } Memo lMemo = maxDist(root.left); Memo rMemo = maxDist(root.right); Memo curMemo = new Memo(-1, 0); // 当前最大深度是左右子树最大深度加1 curMemo.maxDepth = Math.max(lMemo.maxDepth, rMemo.maxDepth) + 1; // 当前最大距离存在于左右子树中 curMemo.maxDist = Math.max(lMemo.maxDist, rMemo.maxDist); // 或者跨越了根节点 curMemo.maxDist = Math.max(curMemo.maxDist, lMemo.maxDepth + rMemo.maxDepth + 2); return curMemo; }}
测试代码
public class Test { static Node binaryTree() { Node root = new Node(); Node root2 = new Node(); root.right = root2; Node l = new Node(); Node r = new Node(); root2.left = l; root2.right = r; Node ll = new Node(); Node lr = new Node(); l.left = ll; l.right = lr; Node rr = new Node(); r.right = rr; Node lrl = new Node(); lr.left = lrl; return root; } public static void main(String[] args) { Node root = binaryTree(); Memo memo = maxDist(root); System.out.println(memo.maxDist); }}
- 最大距离二叉树节点
- 求二叉树节点的最大距离
- 二叉树中节点的最大距离
- 二叉树中节点的最大距离
- 二叉树中节点的最大距离
- 二叉树中节点的最大距离
- 二叉树中节点的最大距离
- 二叉树中节点的最大距离
- 求二叉树节点的最大距离
- 二叉树中节点的最大距离
- 二叉树中节点的最大距离
- 二叉树中节点的最大距离
- 二叉树两节点间最大距离
- 求二叉树节点的最大距离
- 二叉树中节点的最大距离
- 二叉树节点的最大距离---ms
- 求二叉树节点的最大距离
- 求二叉树节点的最大距离
- Excel VBA 移动文件和文件夹
- Office2010安装相关问题及解决方法
- fedora23 安装ffmpeg
- 迷之序列
- DHTML技术综合演示---示例:表格创建2
- 最大距离二叉树节点
- 剑指Offer(第二版)面试题10:斐波那契数列
- 查询策略
- 英语学习可以给我们带来什么
- JavaScript之对象
- Android滚动条广告,可以设置自定义view的ViewSwitcher
- C++面向对象-类继承练习
- excel设置曲线图横坐标值
- 微商该如何起步和成长到大咖?