二叉树每个结点均有权值,设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离

二叉树

(网易2016实习Java研发工程师编程题)

题目描述

有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点权值最小的叶节点距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。

给定二叉树的根节点root,请返回所求距离。

解法一:利用二进制编码



//典型的二进制编码题,算出叶子节点二进制编码,再比编码,计算后缀长度和
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 int max=0;
    private int min=99999;
    private StringBuilder maxcodec;
    private StringBuilder mincodec;
        void PreOrder(TreeNode T,char code,StringBuilder codec){
        if(T!=null){           
            codec.append(code);
            if(T.left==null && T.right==null)
            {
                if(max<T.val)
                {
                    max=T.val;
                    maxcodec = codec;
                }
                 
                if(min>T.val)
                {
                    min=T.val;
                    mincodec = codec;
                }
            }
            PreOrder(T.left,'0',new StringBuilder(codec));
            PreOrder(T.right,'1',new StringBuilder(codec));
        }
    }
    public int getDis(TreeNode root) {
        PreOrder(root,'0',new StringBuilder());
        int index=0;
        for(index=0; index<(maxcodec.length()>mincodec.length()?maxcodec.length():mincodec.length());index++)
        {
            if(maxcodec.charAt(index)!=mincodec.charAt(index))
                break;
        }
        return (maxcodec.substring(index).length()+mincodec.substring(index).length());
     
        // write code here
    }
}

解法二:


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;
	}
}

链接:https://www.nowcoder.com/questionTerminal/d567727f21a247f7b64ba32431cb9a19?f=discussion
来源:牛客网

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值