【二叉树】求二叉树中节点的最大距离

题目:《编程之美》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);


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值