题目:《编程之美》P241
提示:利用动态规划的思想,保存每次循环所计算出来的数据,可以避免重复计算
class treenode
{
public:
int data;
shared_ptr<treenode> left,right;
treenode(int d,const shared_ptr<treenode> &l,const shared_ptr<treenode> &r):data(d),left(l),right(r){}
treenode(){}
treenode(int d) :data(d), left(nullptr), right(nullptr){}
};
int get_distance_core(const shared_ptr<treenode> root,map<shared_ptr<treenode>,pair<int,int>> &cache,int &maxdistance)
{
//已经保存了当前记录,无需计算直接返回
if(cache.find(root)!=cache.end())
return max(cache[root].first,cache[root].second);
int left_len,right_len;
if(root->left==nullptr)
left_len=-1;
else if(cache.find(root->left)!=cache.end())
left_len=max(cache[root->left].first,cache[root->left].second);
else
left_len=get_distance_core(root->left,cache,maxdistance);
if(root->right==nullptr)
right_len=-1;
else if(cache.find(root->right)!=cache.end())
right_len=max(cache[root->right].second,cache[root->right].first);
else
right_len=get_distance_core(root->right,cache,maxdistance);
//记录本次运算的数据
cache.emplace(root,make_pair(left_len+1,right_len+1));
//更新maxdistance
if(left_len+right_len+2>maxdistance)
maxdistance=left_len+right_len+2;
return max(left_len+1,right_len+1);
}
int get_distance(const shared_ptr<treenode> root)
{
if(root==nullptr || (root->left==nullptr && root->right==nullptr) )
return -1;
//cache保存计算出来的每个节点对应的数据
//pair的first是左子树叶子与节点连线的最大距离,pair的second是右子树叶子与节点连线的最大距离
map<shared_ptr<treenode>,pair<int,int>> cache;
int maxdistance=-1;
get_distance_core(root,cache,maxdistance);
return maxdistance;
}
//测试代码
shared_ptr<treenode> p1(new treenode(1));
shared_ptr<treenode> p2(new treenode(2));
shared_ptr<treenode> p3(new treenode(3));
shared_ptr<treenode> p4(new treenode(4));
shared_ptr<treenode> p5(new treenode(5));
shared_ptr<treenode> p6(new treenode(6));
shared_ptr<treenode> p7(new treenode(7));
p1->left=p2;
p1->right=p3;
p2->left=p4;
p4->right=p5;
p3->left=p6;
p3->right=p7;
cout<<get_distance(p1);