您的位置:首页 > 其它

算法:求二叉树中两个节点的最大距离

2017-08-24 23:32 281 查看

问题定义:

如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,定义”距离”为这条路径上所有节点的value和。写一个程序求一棵二叉树中最大的路径距离。



思路:

对于这个图,最大的路径是从5—-3—-7,距离为15的路径。

采用后序遍历,对于每一个节点保存经过当前节点的单边路径的最大距离,定义为single_max,为什么只保存单边距离:对于当前节点的父节点来说,路径只能来自于单边:

定义一个全局变量 max_path,存储最大路径。

1. 对于叶节点,单边最大距离就是它本身,
node.single_max=node.value


2. 对于非叶节点,如果左右子节点都存在的话:

经过左孩子到达当前节点的最大距离:

left_max=max(node.left.value, node.left.single_max)


经过右孩子到达当前节点的最大距离:

right_max=max(node.right.value, node.right.single_max)


从子节点到当前节点的最大单边距离:

node.single_max=max(node.value, node.value+max(left_max, right_max))


更新可能的最大距离

current_max=max(node.value, node.single_max)
max_path=max(current_max, current_max+left_max+right_max)


3.对于非叶节点,如果左右子节点只存在一个,还是按照第二条的逻辑去处理。

递归前面的步骤到达根节点,即可求出最终的最大距离:



伪代码:

void generate_max_distance(Node* root){
int result=INT_MIN;
helper(root, result);
return result;
}
void helper(Node* node, int& result){
if(node==nullptr)
return;
helper(node->left, result);

4000
helper(node->right, result);
if(node->left && node->right){//左右子树都存在
...
}else if(node->left){  //只有左子节点
...
}else{  //只有右子节点
...
}
return;
}


更新

这个问题其实是LeetCode 的124. Binary Tree Maximum Path Sum

/*

这道题是求树的路径和的题目,不过和平常不同的是这里的路径不仅可以从根到某一个结点,

* 而且路径可以从左子树某一个结点,然后到达右子树的结点,就像题目中所说的可以起始和终结于任何结点。

* 可以用0作为返回值,这样就不用区别有没有子树的情况了。

* 算法的本质还是一次树的遍历,所以复杂度是O(n)。而空间上仍然是栈大小O(logn)。

*/

代码:

/**
* Definition for binary tree
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxPathSum(TreeNode *root) {
if(root == nullptr)
return 0;
int max_sum=INT_MIN;
maxPathHelper(root,max_sum);
return max_sum;

}
int maxPathHelper(TreeNode *root,int &max_sum){
if(root==nullptr)
return 0;
//因为节点的值可以为负数,所以最大值取0和子树值的较大者
int max_left=max(0,maxPathHelper(root->left,max_sum));
int max_right=max(0,maxPathHelper(root->right,max_sum));
//如果将当前root作为根节点,那么最大值是root.val+左子树最大值+右子树最大值
int cur_max=max_left+root->val+max_right;
if(cur_max > max_sum)
max_sum=cur_max;
//只能返回左右子树中较大值加上root.val,也就是单边距离
return root->val +max(max_left,max_right);
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐