有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。
给定二叉树的根节点root,请返回所求距离。
class Tree { public: vector<int> min_path; vector<int> max_path; int mmin; int mmax; int getDis(TreeNode* root) { mmin = numeric_limits<int>::max(); mmax = numeric_limits<int>::min(); vector<int> vec; dfs(root,vec); if(min_path.size() == 0) return 0; for(int i =0;;i++) { if(min_path[i] == max_path[i]) continue; else { return min_path.size() - i + max_path.size() - i; } } } void dfs(TreeNode* root,vector<int> &vec) { if(root == NULL) return ; if((root->left == NULL) && (root->right == NULL)) { if(root->val < mmin) { mmin = root->val; min_path.assign(vec.begin(),vec.end()); } if(root->val > mmax) { mmax = root->val; max_path.assign(vec.begin(),vec.end()); } } vec.push_back(-1); dfs(root->left,vec); vec.pop_back(); vec.push_back(1); dfs(root->right,vec); vec.pop_back(); } };
首先深度遍历所有的叶子节点,在遍历的同时记录叶子节点的路径。记录下最小的叶子节点路径。 因为所有的路径都是从根节点出发的,所以-1表示向左,1表示向右。那么记录下最小叶子的路径,和最大叶子的路径。 然后比较一下他们相同的前缀,剩下的值相加就是最后的答案
//1注意点 权值最大的叶子节点到权值最小的叶子节点,不是所有的节点,自己就因为这个卡了好久 //2.用俩个变量标记俩个节点的位置,求出根节点到他们的路径,如果有重复的路径就减去重复的路径的长度. class Tree { void Inorder(TreeNode *root,vector<int>&v,int &small,int &big){ //中序遍历获得最小的叶节点和最大的叶节点的索引 if(!root) return; Inorder(root->left, v, small, big); v.push_back(root->val); if(root->left==NULL&&root->right==NULL){//叶子节点 if(small==-1||big==-1) small = big =(int)v.size()-1; else{ if(root->val<v[small]) small = (int)v.size()-1; if(root->val>v[big]) big = (int)v.size()-1; } } Inorder(root->right, v, small, big); } public: int getDis(TreeNode* root) { int small = -1,big = -1; vector<int>v; Inorder(root, v, small, big); TreeNode * p = root; vector<int>v1,v2; int pos; while (true) {//寻找路径 pos = (int)(find(v.begin(), v.end(),p->val)-v.begin()); v1.push_back(v[pos]); if(small>pos) p = p->right; else if(small<pos) p = p->left; else break; } p = root; while (true) { pos = (int)(find(v.begin(), v.end(),p->val)-v.begin()); v2.push_back(v[pos]); if(big>pos) p = p->right; else if(big<pos) p = p->left; else break; } int i,j; for (i=0,j=0;j<v2.size()-1&&i<v1.size()-1; ++i,++j) {//去重 if(!(v1[i]==v2[j]&&v1[i+1]==v2[j+1])) break; } return (int)v1.size()-1+(int)v2.size()-1-2*i; } };
class Tree{ public: int min_key = INT_MAX; int min_level; int max_level; int max_key = INT_MIN; void find_min_max(TreeNode* root, int level) { if (root == NULL)return; if (!root->left && !root->right && root->val < min_key) { min_key = root->val; min_level = level; } if (!root->left && !root->right && root->val > max_key) { max_key = root->val; max_level = level; } find_min_max(root->left, level + 1); find_min_max(root->right, level + 1); } int find_level(TreeNode* root, int key) { if (root == NULL)return -1; if (key == root->val)return 0; int level = find_level(root->left, key); if (level == -1) level = find_level(root->right, key); if (level != -1) return level + 1; return -1; } TreeNode* find_father(TreeNode* root, int key1, int key2) { if (root == NULL || key1 == root->val || key2 == root->val) return root; TreeNode* left = find_father(root->left, key1, key2); TreeNode* right = find_father(root->right, key1, key2); if (left && right)return root; return left ? left : right; } int getDis(TreeNode* root) { find_min_max(root, 0); TreeNode* father = find_father(root, min_key, max_key); int father_level = find_level(root, father->val); return min_level + max_level - 2 * father_level; } };
int getDis(TreeNode* root) { // write code here map<int, pair<int,int>>parent;//不同权值对应的父亲(权值和编号) queue<TreeNode*>que;//辅助队列,按层遍历找父节点 que.push(root); int max = -1000;//最大权值 int min = 1000;//最小权值 parent[root->val]=make_pair(0,0);//根节点的父节点 int cnt = 0;//起始编号 while (!que.empty()){ TreeNode*temp = que.front();//队首元素 cnt++; if (temp->left){ parent[(temp->left)->val]=make_pair(temp->val,cnt); que.push(temp->left); } if (temp->right){ parent[(temp->right)->val]=make_pair(temp->val,cnt); que.push(temp->right); } if (temp->left == NULL&&temp->right == NULL){//如果是子节点 if ((temp->val)>max){ max = temp->val; } if ((temp->val)<min){ min = temp->val; } } que.pop(); } int result1 = 0; int result2 = 0; while(max!=min){ if(parent[max].second>parent[min].second){ max=parent[max].first; result1++; } else if(parent[min].second>parent[max].second){ min=parent[min].first; result2++; } else{ max=parent[max].first; min=parent[min].first; result2++; result1++; } } return result1 + result2; }
import java.util.*; public class Tree { public int getDis(TreeNode root) { // 层次遍历找到最值叶节点 Queue<TreeNode> queue = new LinkedList<>(); TreeNode minNode = root; TreeNode maxNode = root; queue.offer(root); while(!queue.isEmpty()){ TreeNode cur = queue.poll(); if(cur.left == null && cur.right == null){ if(cur.val > maxNode.val){ maxNode = cur; }else if(cur.val < minNode.val){ minNode = cur; } } if(cur.left != null){ queue.offer(cur.left); } if(cur.right != null){ queue.offer(cur.right); } } // 寻找最值节点的最近公共祖先 TreeNode lcaNode = lowestCommonAncestor(root, minNode, maxNode); // 计算距离 return disBetweenNode(lcaNode, minNode) + disBetweenNode(lcaNode, maxNode); } // 层次遍历计算距离 private int disBetweenNode(TreeNode node1, TreeNode node2) { int dis = 0; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(node1); while(!queue.isEmpty()){ int queueSize = queue.size(); for(int i = 0; i < queueSize; i++){ TreeNode cur = queue.poll(); if(cur == node2){ return dis; } if(cur.left != null){ queue.offer(cur.left); } if(cur.right != null){ queue.offer(cur.right); } } dis++; } return dis; } private TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if(root == null || root == p || root == q) return root; TreeNode left = lowestCommonAncestor(root.left, p, q); TreeNode right = lowestCommonAncestor(root.right, p, q); if(left == null) return right; if(right == null) return left; return root; } }
# -*- coding:utf-8 -*- # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None ''' 最高赞的python版 ''' class Tree: ma = 0 macode = '' mi = 9999 micode = '' def getDis(self, root): # write code here if not root: return 0 def getCode(root,code,codec): if root: codec += code if root.left == None and root.right == None: if root.val > self.ma: self.ma = root.val self.macode = codec if root.val < self.mi: self.mi = root.val self.micode = codec getCode(root.left,'0',codec) #codec.pop() getCode(root.right,'1',codec) getCode(root,'-1','') #print macode,micode lma = len(self.macode) lmi = len(self.micode) #return lma i = 0 while i < min(lma,lmi): if self.macode[i] != self.micode[i]: r = lma-i+lmi-i return r i += 1
import java.util.*; public class Tree { public int max_node_value = -1; public int min_node_value = -1; public LinkedList<Integer> road = new LinkedList<Integer>(); public LinkedList<Integer> min_road = new LinkedList<Integer>(); public LinkedList<Integer> max_road = new LinkedList<Integer>(); public int getDis(TreeNode root) { road.addLast(root.val); dfs(root); while (max_road.getFirst() == min_road.getFirst()) { max_road.removeFirst(); min_road.removeFirst(); } return max_road.si敏感词_road.size(); } public void dfs(TreeNode node) { if (node.left == null && node.right == null) { if (max_node_value == -1) { max_node_value = node.val; max_road = (LinkedList<Integer>) road.clone(); } else if (max_node_value < node.val) { max_node_value = node.val; max_road = (LinkedList<Integer>) road.clone(); } if (min_node_value == -1) { min_node_value = node.val; min_road = (LinkedList<Integer>) road.clone(); } else if (min_node_value > node.val) { min_node_value = node.val; min_road = (LinkedList<Integer>) road.clone(); } return; } if (node.left != null) { road.addLast(node.left.val); dfs(node.left); road.removeLast(); } if (node.right != null) { road.addLast(node.right.val); dfs(node.right); road.removeLast(); } } }
//后续遍历树,并打印从根节点到叶子节点的路径
class Tree { public: int getDis(TreeNode* root) { if(!root) return 0; vector<TreeNode*> vec,max,min; TreeNode* p=root,*q; do{ while(p){ vec.push_back(p); p=p->left; } q=NULL; while(!vec.empty()){ p=vec.back(); vec.pop_back(); if(p->right==q){ q=p; if(!p->left&&!p->right){ vec.push_back(p); if(max.size()==0||max.back()->val<vec.back()->val) max=vec; if(min.size()==0||min.back()->val>vec.back()->val) min=vec; vec.pop_back(); } }else{ vec.push_back(p); p=p->right; break; } } }while(!vec.empty()); int i; for(i=0;i<max.size()&&i<min.size()&&max[i]==min[i];i++); return max.size()-2*i+min.size(); } };
//这个题关键是找到最大结点和最小结点刚开始分叉的地方,也就是共有路径的结束点。那么最后的距离就等于(最大结点的路径长度-共有路径长度)+(最小结点的路径长度-共有路径长度) //可以采取哈夫曼编码树的方法,记录从根结点到该结点的唯一路径。如:0101 //题目说权值各不相同,所以可以用权值作为该结点的唯一ID; //以上就是我们需要记录的信息,有两个,结点ID(权值)和到该结点的路径。 //对于路径的存储,我们采用一个队列来存储,遍历时每往树的下层走一步,就在队列里加0(左子树)或1(右子树) //所以我们采取深度优先遍历DFS,并且遍历完成后记录每个结点的ID和路径信息。函数UpdateWhileDFS //信息保存在一个MAP里,MAP的结构为<权值,路径>,这样根据结点权值,就可以取出到该结点的路径。 class Tree{ private: int max = -999999; int min = 999999; //存储信息的MAP,MAP的结构为<权值,路径> unordered_map<int, queue<int>> info; public: void UpdateWhileDFS(TreeNode* root, queue<int> path,int mark){ //mark为哈夫曼编码,取0或1.左子树为0,右子树为1.根节点为NULL //更新结点路径 path.push(mark); //存储结点路径 info[root->value] = path; //更新最大值 if (root->value > max) max = root->value; //更新最小值 if (root->value < min) min = root->value; //递归遍历左子树 if (root->left != NULL) //左子树的哈夫曼编码是0,所以告诉函数你应该在路径的最后加0 UpdateWhileDFS(root->left, path,0); if (root->right != NULL) //右子树的哈夫曼编码是0,所以告诉函数你应该在路径的最后加1。
UpdateWhileDFS(root->right, path, 1); }
int getDis(TreeNode * root){
//队列用于存储路径
queue<int> q;
//初始化根结点的路径队
info[root->value] = q;
//遍历,并更新路径信息。
UpdateWhileDFS(root, info[root->value],NULL);
//取出最大结点的路径
queue<int> maxQueue = info[max];
//取出最小结点的路径
queue<int> minQueue = info[min];
//利用循环去掉共有路径
while (!maxQueue.empty()&& !minQueue.empty())
{
if (maxQueue.front()!=minQueue.front())
break;
maxQueue.pop();
minQueue.pop();
}
//循环结束,说明此时到达分叉点
return maxQueue.si敏感词Queue.size();
}
};
#include <iostream> #include <vector> #include <string> #include <queue> #include <unordered_map> #include <map> #include <algorithm> using namespace std; struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; //以前序遍历创建二叉树 void CreateBiTree(TreeNode **T)//*T是指向BiTNode的指针 { *T=new TreeNode(0); if(*T==NULL)//如果*T还是指向NULL,表示内存分配失败,退出程序 exit(OVERFLOW); char ch; cin>>ch; if(ch=='#') *T=NULL; else { (*T)->val=ch-'0';//*T指向的节点的data分配内容,即生成根节点 CreateBiTree(&((*T)->left));//创建&(*T)->lchild临时变量,传入CreateBiTree,构造左子树 CreateBiTree(&((*T)->right));//创建&(*T)->rchild临时变量,传入CreateBiTree,构造右子树 } } /* 分两大步 1 标记每个节点的父节点,并且找出最大叶节点和最小叶节点 用map<int,pair<int,int>>标记每个子节点的父节点,first是子节点值,second是<父节点值,父节点位置> 用queue遍历二叉树的节点 依次把每个父节点的子节点push进队列,每取出一个节点处理,计数加1,然后处理取出节点的左右孩子进行标记 处理完之后,把取出的节点pop出去 2 计算两个叶节点的最短路径 分别找出两个叶节点到树根的路径,公共部分以前的路径相加即最短路径 */ class Tree { public: int getDis(TreeNode* root) { // write code here //第1步 map<int, pair<int, int>> parent;//标记每个子节点的父节点 queue<TreeNode*> que;//按照层序遍历处理每个节点 que.push(root); parent[root->val] = make_pair(0, 0);//树根的双亲设置为(0,0) int max = -65535; int min = 65536; int cnt = 0;//每处理一个节点计数加1 while (!que.empty()) { //处理队列里的每个节点,每处理一个,计数加1。即cnt是目前处理的节点的序号(按层序遍历标序)。 TreeNode* temp = que.front(); cnt++; //处理该节点的左右孩子 if (temp->left)//如果该节点有左孩子,标记左孩子,并且把左孩子入队列 { parent[(temp->left)->val] = make_pair(temp->val, cnt); que.push(temp->left); } if (temp->right)//如果该节点有右孩子,标记右孩子,并且把右孩子入队列 { parent[(temp->right)->val] = make_pair(temp->val, cnt); que.push(temp->right); } if (temp->left == NULL &&temp->right == NULL)//如果该节点是叶子节点,需要比较它和max和min的大小 { if (temp->val > max) max = temp->val; if (temp->val < min) min = temp->val; } que.pop(); } //第2步 vector<int> v1; vector<int> v2; v1.push_back(min); v2.push_back(max); int move1 = min; int move2 = max; while(parent[move1].second > 0)//把min到树根的路径找出来 { v1.push_back(parent[move1].first); move1 = parent[move1].first; } while (parent[move2].second > 0)//把max到树根的路径找出来 { v2.push_back(parent[move2].first); move2 = parent[move2].first; } //反转一下方便查找公共串,第一个节点都是树根 reverse(v1.begin(), v1.end()); reverse(v2.begin(), v2.end()); int n = 0; for (;v1[n] == v2[n];n++);//n是公共串的结尾 return (v1.size() + v2.size() - 2 * n); } }; //测试 int main() { TreeNode **pp;//定义指向BiTNode的二级指针pp TreeNode *p;//定义指向BiTNode的指针p pp=&p;//pp指向p p=NULL;//初始化p指向NULL CreateBiTree(pp);//传入指向p的地址,创建二叉树,输入5129###3##4#68##7## Tree solution; cout << solution.getDis(p); return 0; }
class Tree: def getDis(self, root): # 层次遍历 O(N) max_leaf, min_leaf, parents = self.level_triversal(root) # 构造出从权值最大/最小的叶子结点到根节点的路径 2*O(lg(N)) max_leaf_to_root = self.construct_path(max_leaf, root.val, parents) min_leaf_to_root = self.construct_path(min_leaf, root.val, parents) # 路径上的公共父结点,至少包含一个root结点 com_nodes = list(set(max_leaf_to_root).intersection( set(min_leaf_to_root))) # 计算距离 dis = (len(max_leaf_to_root) - 1) + (len(min_leaf_to_root) - 1) if len(com_nodes) > 1: # 此时需要去掉重复边 dis -= len(com_nodes) return dis def level_triversal(self, root): """ 层次遍历,并记录权值最大的叶子结点max_leaf、 权值最小的叶子结点min_leaf、父子关系parents """ queue = [] queue.append(root) parents = {} parents[root.val] = None max_leaf = None min_leaf = None while len(queue) > 0: cur = queue.pop(0) if cur.left is None and cur.right is None: if max_leaf is None or max_leaf < cur.val: max_leaf = cur.val if min_leaf is None or cur.val < min_leaf: min_leaf = cur.val if cur.left is not None: queue.append(cur.left) parents[cur.left.val] = cur.val if cur.right is not None: queue.append(cur.right) parents[cur.right.val] = cur.val return (max_leaf, min_leaf, parents) def construct_path(self, begin, end, parents): """ 根据父子关系构造出从begin到end的路径 """ cur = begin queue = [] while cur != end: queue.append(cur) cur = parents[cur] queue.append(cur) return queue
//典型的二进制编码题,算出叶子节点二进制编码,再比编码,计算后缀长度和 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 heregetMaxMin(root);//找到最大最小叶子节点TreeNode lcaNode = getLCA(root);//找LCAint 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;}
//受大神们的启发,找路径,然后去重,代码较短。时间复杂度应该就是遍历二叉树的复杂度。 class Tree { public: void getCode(map<int, string>&m, TreeNode*root,string s) { if (root->left == NULL && root->right == NULL) { m[root->val] = s; //记录每一个叶子的权值和编码 return; } if (root->left) { getCode(m, root->left, (s + '1')); } if (root->right) { getCode(m, root->right, (s + '0')); } } int getDis(TreeNode* root) { // write code here map<int, string>m;//<权值,编码> string s; getCode(m, root,s); auto it = m.begin(); string s1 = it->second; auto end = (--m.end()); string s2 = end->second; int i = 0, j = 0; for (; i < s1.size() && j < s2.size()&&s1[i] == s2[j]; i++, j++) {} return s1.size() - i + s2.size() - j; } };
class Tree: def __init__(self): self.max = 0 self.min = 99999 self.maxpath = [] self.minpath = [] def getDis(self, root): # write code here code = '' self.midOrder(root,'0',code) a = self.minpath b = self.maxpath for i in range(0,min(len(a),len(b))): if a[i] != b[i]: result = len(a[i:]+b[i:]) break return result def midOrder(self,root,Flag,code): if root == None: return code = code + Flag if root.left == None and root.right == None: if self.max < root.val: self.max = root.val self.maxpath = code if self.min > root.val: self.min = root.val self.minpath = code self.midOrder(root.left,'0',code) self.midOrder(root.right,'1',code)
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 { public int getDis(TreeNode root) { // write code here // 妈呀,这也太难了吧 // 我需要做的是,从一个角落开始给每一个节点编号,中序遍历是可以的。但很麻烦,想不到 if(root==null) return -1; else if(root.left==root.right&&root.left==null) return 0; Map<Integer,Integer> record = new HashMap<>(); Map<Integer,Integer> father = new HashMap<>(); //用这个记录每个权值对应的dis int min = Integer.MAX_VALUE; int max = Integer.MIN_VALUE; // 我可以将根节点的depth设置为0,左子树的深度按照正的增加,右子树的深度按照负的增加 // record.put(root.val,0);//root肯定不是叶节点了 //然后我还是可以按照广度优先 ArrayList<TreeNode> nodes = new ArrayList<>(); if(root.left!=null){ nodes.add(root.left); record.put(root.left.val,1); father.put(root.left.val,root.val); } if(root.right!=null){ nodes.add(root.right); record.put(root.right.val,-1); father.put(root.right.val,root.val); } int index = 0 ; while(index<nodes.size()){//我真的觉得自己没做错啊。这个确实没错,但这是所有节点啊啊啊啊啊啊 TreeNode node = nodes.get(index); if(node.left==null&&node.right==null){ if(node.val>max) max=node.val; if(node.val<min) min=node.val; index++; continue; } int thisdepth = record.get(node.val); thisdepth=thisdepth>0?thisdepth+1:thisdepth-1; if(node.left!=null){ nodes.add(node.left); record.put(node.left.val,thisdepth); father.put(node.left.val,node.val); } if(node.right!=null){ nodes.add(node.right); record.put(node.right.val,thisdepth); father.put(node.right.val,node.val); } index++; } //要考虑的问题还有哦,如果max和min同在左子树或者右子树呢? //那你还得找到他们第一个共同祖先?好像又麻烦了哦,那就再加一个Map吗?用空间换时间,那会不会,超出啊 if(record.get(min)*record.get(max)<0) return Math.abs(record.get(min)-record.get(max)); else{ //找共同的祖先活动开始,吓死我了,没有超过空间限制。 int father1 = father.get(min); int father2 = father.get(max); while(father1!=father2){ father1 = father.get(father1); father2 = father.get(father2); } int father_depth = record.get(father1); return Math.abs(2*father_depth-record.get(min)-record.get(max)); } } }
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 { public int getDis(TreeNode root) { // write code here fun(root,"0"); char[] minchars=minstr.toCharArray(); char[] maxchars=maxstr.toCharArray(); int i; for(i=0;i<minchars.length&&i<maxchars.length;i++) if(minchars[i]!=maxchars[i]) break; return minchars.length+maxchars.length-i*2; } int min=Integer.MAX_VALUE; int max=0; String minstr; String maxstr; void fun(TreeNode node,String str) { if(node==null) return; if(node.left==null&&node.right==null) { if(min>node.val) { min=node.val; minstr=str; } if(max<node.val) { max=node.val; maxstr=str; } } fun(node.left,str+'0'); fun(node.right,str+'1'); } }
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 { Map<TreeNode,TreeNode> map = new HashMap();//记录父节点 List<TreeNode> leaf = new ArrayList();//记录叶子节点 public int getDis(TreeNode root) { TreeNode arr[] = max_and_min(root);//找到最大和最小的叶子节点 TreeNode node1 = arr[0]; TreeNode node2 = arr[1]; List<TreeNode> max_road = new ArrayList();//最大叶子节点的回溯路径 List<TreeNode> min_road = new ArrayList();//最小叶子节点的回溯路径 Map<TreeNode,Integer> len1 = new HashMap();//记录当前父节点到最大叶子节点的距离 Map<TreeNode,Integer> len2 = new HashMap();//记录当前父节点到最小叶子节点的距离 int t1=0,t2=0;//临时变量 while(node1!=null){ max_road.add(node1); len1.put(node1,t1++); node1 = map.get(node1); } while(node2!=null){ min_road.add(node2); len2.put(node2,t2++); node2 = map.get(node2); } TreeNode same_parent = null;//共同父节点 int tag = 0; for(int i=0;i<max_road.size()&&tag==0;i++){//遍历找到相同的父节点 for(int j=0;j<min_road.size();j++){ if(max_road.get(i)==min_road.get(j)){ same_parent = max_road.get(i); tag = 1; break; } } } return len1.get(same_parent)+len2.get(same_parent); } public TreeNode[] max_and_min(TreeNode root){//广度优先遍历找到最大和最小叶子节点; if(root==null) return null; List<Integer> list = new ArrayList(); Queue<TreeNode> queue = new LinkedList(); queue.offer(root); map.put(root,null); while(!queue.isEmpty()){ int size = queue.size(); while(size>0){ TreeNode temp = queue.poll(); if(temp.left==null&&temp.right==null){ list.add(temp.val); leaf.add(temp); } if(temp.left!=null){ queue.offer(temp.left); map.put(temp.left,temp); } if(temp.right!=null){ queue.offer(temp.right); map.put(temp.right,temp); } size--; } } TreeNode[] res = new TreeNode[2]; int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for(int i=0;i<list.size();i++){ if(max<list.get(i)) max = list.get(i); if(min>list.get(i)) min = list.get(i); } TreeNode leaf_max=null,leaf_min=null; for(int i=0;i<leaf.size();i++){ if(leaf.get(i).val==max){ leaf_max = leaf.get(i); break; } } for(int i=0;i<leaf.size();i++){ if(leaf.get(i).val==min){ leaf_min = leaf.get(i); break; } } res[0] = leaf_max; res[1] = leaf_min; return res; } }