题目
题目描述
给定一棵树,求出这棵树的直径,即树上最远两点的距离。
示例1的树如下图所示。其中4到5之间的路径最长,是树的直径,距离为5+2+4=11
示例1
输入
复制
6,[[0,1],[1,5],[1,2],[2,3],[2,4]],[3,4,2,1,5]
返回值
复制
11
解析
先遍历树,构建一个无向图~
后序遍历更新树的直径。某节点直径=左孩子深度+右孩子深度
/**
* struct Interval {
* int start;
* int end;
* };
*/
class Solution {
public:
//后序遍历node节点
int postOrder(unordered_map<int, vector<pair<int,int>>> &tree, int node, int &res,int parent){
//记录所有子节点(不是二叉树)
vector<int> children;
//遍历节点的所有子节点
for(auto child : tree[node]){
//不能指向父亲
if(child.first != parent){
//后序遍历
int len = postOrder(tree,child.first,res,node);
//计算子节点深度~
children.push_back(child.second + len);
}
}
if(children.size() == 0){
return 0;
}
//降序排序
sort(children.begin(),children.end(),greater<int>());
int len = children[0];
int maxLen = len;
if(children.size() > 1){
maxLen += children[1];
}
//更新最大直径
res = max(maxLen,res);
return len;
}
/**
* 树的直径
* @param n int整型 树的节点个数
* @param Tree_edge Interval类vector 树的边
* @param Edge_value int整型vector 边的权值
* @return int整型
*/
int solve(int n, vector<Interval>& Tree_edge, vector<int>& Edge_value) {
//判空
if(Tree_edge.size() == 0){
return 0;
}
//tree:各条边的起点为key,以(边的终点,权值)为value
unordered_map<int, vector<pair<int,int>>> tree;
//遍历树
for(int i=0;i<Tree_edge.size();i++){
//获取边的信息~
Interval edge = Tree_edge[i];
int value = Edge_value[i];
//为空时,初始化空间
if(tree.find(edge.start) == tree.end()){
tree[edge.start] = vector<pair<int,int>>();
}
if(tree.find(edge.end) == tree.end()){
tree[edge.end] = vector<pair<int,int>>();
}
//往tree中添加节点信息(双向)。
tree[edge.start].push_back(make_pair(edge.end,value));
tree[edge.end].push_back(make_pair(edge.start,value));
}
int res = 0;
int root = Tree_edge[0].start;
//后续遍历
postOrder(tree,root,res,root);
return res;
}
};