二叉树求最大最小叶子节点距离
2016-08-01 00:00
183 查看
摘要: 网易2016题:http://www.nowcoder.com/profile/908327/test/3957872/44580#summary
题目描述:
有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。
给定二叉树的根节点root,请返回所求距离。
思路:
先求最大最小叶子节点,再求两节点的LCA(最近公共祖先),求两节点到LCA距离。
首先得先明白如何求LCA(LCA属于比较经典的一类考点,定要掌握)。
最近祖先节点:
最近祖先节点就是从根节点遍历到给定节点时的最后一个相同节点。
如上图,H和J的最低祖先节点是A。
因为从根节点Root到H的链路为: Root A C H
从根节点Root到J的链路为: Root A D J
查看链路节点可知,A是最后一个相同节点,也就是最近公共父节点或者说最低祖先节点是A。
实现LCA有两种方式,递归和非递归,此处仅介绍递归方式。
LCA思路:
如果给定pRoot是NULL,即空树,则返回的公共节点自然就是NULL;
如果给定pRoot与两个节点中任何一个相同,说明,pRoot在就是所要找的两个节点之一,则直接返回pRoot,表明在当前链路中找到至少一个节点;
如果给定pRoot不是两个节点中任何一个,则说明,需要在pRoot的左右子树中重新查找,此时有三种情况:两个节点都在左子树上;两个节点都在右子树上;一个在左子树,一个在右子树上;具体来说,就是:
情况一:如果左子树查找出的公共节点是NULL,则表明从左子树根节点开始到左子树的所有叶子节点等所有节点中,没有找到两个节点中的任何一个,这就说明,这两个节点不在左子树上,不在左子树,则必定在右子树上;
情况二:如果右子树查找的公共节点是NULL,说明在右子树中无法找到任何一个节点,则两个节点必定在左子树上;
情况三: 如果左右子树查找的公共节点都不是NULL,说明左右子树中各包含一个节点,则当前节点pRoot就是最低公共节点,返回就可以了。
三种情况是互斥的, 只能是其中之一。
参考地址:http://blog.csdn.net/beitiandijun/article/details/41970417
知道LCA实现之后,就简单多了。
Java代码实现
知识是需要一点一点累积的!
题目描述:
有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。
给定二叉树的根节点root,请返回所求距离。
思路:
先求最大最小叶子节点,再求两节点的LCA(最近公共祖先),求两节点到LCA距离。
首先得先明白如何求LCA(LCA属于比较经典的一类考点,定要掌握)。
最近祖先节点:
最近祖先节点就是从根节点遍历到给定节点时的最后一个相同节点。
如上图,H和J的最低祖先节点是A。
因为从根节点Root到H的链路为: Root A C H
从根节点Root到J的链路为: Root A D J
查看链路节点可知,A是最后一个相同节点,也就是最近公共父节点或者说最低祖先节点是A。
实现LCA有两种方式,递归和非递归,此处仅介绍递归方式。
LCA思路:
如果给定pRoot是NULL,即空树,则返回的公共节点自然就是NULL;
如果给定pRoot与两个节点中任何一个相同,说明,pRoot在就是所要找的两个节点之一,则直接返回pRoot,表明在当前链路中找到至少一个节点;
如果给定pRoot不是两个节点中任何一个,则说明,需要在pRoot的左右子树中重新查找,此时有三种情况:两个节点都在左子树上;两个节点都在右子树上;一个在左子树,一个在右子树上;具体来说,就是:
情况一:如果左子树查找出的公共节点是NULL,则表明从左子树根节点开始到左子树的所有叶子节点等所有节点中,没有找到两个节点中的任何一个,这就说明,这两个节点不在左子树上,不在左子树,则必定在右子树上;
情况二:如果右子树查找的公共节点是NULL,说明在右子树中无法找到任何一个节点,则两个节点必定在左子树上;
情况三: 如果左右子树查找的公共节点都不是NULL,说明左右子树中各包含一个节点,则当前节点pRoot就是最低公共节点,返回就可以了。
三种情况是互斥的, 只能是其中之一。
public TreeNode GetLastCommonParent( TreeNode pRoot, TreeNode pNode1, TreeNode pNode2){ if( pRoot == null ) //说明是空树,不用查找了,也就找不到对应节点,则返回NULL return null; if( pRoot == pNode1 || pRoot == pNode2 )//说明在当前子树的根节点上找到两个节点之一 return pRoot; TreeNode pLeft = GetLastCommonParent( pRoot.left, pNode1, pNode2); //左子树中的查找两个节点并返回查找结果 TreeNode pRight = GetLastCommonParent( pRoot.right, pNode1, pNode2);//右子树中查找两个节点并返回查找结果 if( pLeft == null )//如果在左子树中没有找到,则断定两个节点都在右子树中,可以返回右子树中查询结果;否则,需要结合左右子树查询结果共同断定 return pRight; if ( pRight == null )//如果在右子树中没有找到,则断定两个节点都在左子树中,可以返回左子树中查询结果;否则,需要结合左右子树查询结果共同断定 return pLeft; return pRoot;//如果在左右子树中都找两个节点之一,则pRoot就是最低公共祖先节点,返回即可。 }
参考地址:http://blog.csdn.net/beitiandijun/article/details/41970417
知道LCA实现之后,就简单多了。
Java代码实现
import java.util.*; /* public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } }*/ public class Tree { private TreeNode maxNode = new TreeNode(Integer.MIN_VALUE); private TreeNode minNode = new TreeNode(Integer.MAX_VALUE); public int getDis(TreeNode root) { // write code here getMaxMin(root);//找到最大最小叶子节点 TreeNode lcaNode = getLCA(root);//找LCA int a = getNodeDis(lcaNode, maxNode);//最大值叶子节点到LCA的距离; int b = getNodeDis(lcaNode, minNode);//最小值叶子节点到LCA的距离; return a+b; } // 先找到最大最小叶子节点 public void getMaxMin(TreeNode root) { if (root == null) { return; } if (root.left == null && root.right == null) { if (root.val > maxNode.val) { maxNode = root; } else if (root.val < minNode.val) { minNode = root; } } getMaxMin(root.left); getMaxMin(root.right); } // LCA最近公共祖先 public TreeNode getLCA(TreeNode root) { if (root == null) {// 说明是空树 return null; } if (root.val == maxNode.val || root.val == minNode.val) {// 在当前树的根节点上找到两个节点之一 return root; } TreeNode leftNode = getLCA(root.left);// 左子树中的查找两个节点并返回查找结果 TreeNode rightNode = getLCA(root.right);// 右子树中查找两个节点并返回查找结果 if (leftNode == null) {// 左子树中没找到,则一定在右子树上 return rightNode; } else if (rightNode == null) {// 右子树没找到一定在左子树上 return leftNode; } else {// 左右子树均找到一个节点,则根节点为最近公共祖先 return root; } } //获取叶子节点到LCA距离 public int getNodeDis(TreeNode lcaNode, TreeNode node){ if(lcaNode==null){ return -1; } if(lcaNode.val==node.val){ return 0; } //三种情况:两个均在左子树;两个均在右子树;一左一右,所以不能用if-elseif结构 int distance = getNodeDis(lcaNode.left, node);//左子树未找到两个节点之一 if(distance==-1){ distance = getNodeDis(lcaNode.right, node); } if(distance!=-1){ return distance+1; } return -1; }
知识是需要一点一点累积的!
相关文章推荐
- 先序遍历建立二叉树,求保存最大数字的叶子节点到最小数字的叶子结点的距离 2016网易编程题
- 搜狐研究院 求二叉树最大叶子节点到最小叶子节点的距离
- 二叉树权值最大的叶子节点到权值最小的叶子节点的距离
- 网易——求二叉树最大叶子节点到最小叶子节点的距离
- 求二叉树的最大叶子节点距离(递归)
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 求 二叉树中权值最大和最小的叶节点之间的距离
- 二叉树中权值最大的叶节点到权值最小的叶节点的距离
- 二叉树中最大最小权值节点距离问题
- 面试题5:计算二叉树中最大节点到最小节点之间的距离
- 二叉树系列——二叉树的最大距离(即相距最远的两个叶子节点,编程之美,百度面试题)
- 求二叉树最大叶子节点距离(不含全局变量)
- 利用栈结构实现二叉树的非递归遍历,求二叉树深度、叶子节点数、两个结点的最近公共祖先及二叉树结点的最大距离
- 编程之美3.8 求二叉树中节点的最大距离
- 11.求二叉树中节点的最大距离...
- 二叉树中节点的最大距离--递归和非递归
- 二叉树中节点的最大距离
- c++实现二叉树中节点的最大距离
- 求二叉树中节点的最大距离