二叉树中的节点x含有一个变量wealth表征了该节点的财富,定义二叉树中节点x的Heritage为其祖先节点(包括x)的所有wealth之和减去节点x的子孙节点的所有wealth之和。求二叉树中Heritage最大的节点及其值。【要求不能改变原有二叉树的结构,不能在节点之上存储别的信息,算法复杂度尽量简单】
看到这个题目,最简单的思路就是二叉树的遍历。第一种思路是进行两次遍历,第一次遍历是全局遍历,第二次遍历是寻找祖先节点和子孙节点并计算其差。很明显,算法复杂度是O(n^2)。
很明显这样的复杂度过高。如何进行一次遍历来求得解呢?可以考虑一般的情况,我们考虑节点x为根的子树,以及x的左孩子x.left和x的右孩子x.right。当我们获知x.left或者x.right中具有最大的Heritage的节点后,很明显,以节点x为根的子树中,具有最大Heritage的节点只可能有三种情况:
一是节点x本身,二是x.left中具有最大的Heritage的节点,三是x.right中具有最大的Heritage的节点。
究竟是那种情况呢?
这取决于它们之间Heritage的大小。其一是x.wealth - TreeWorthOfLeft - TreeWorthOfRight,即节点x的Heritage。TreeWorthOfLeft表示x的所有左子树wealth之和,TreeWorthOfRight表示x所有右子树wealth之和。其二是MaxHeritageOfLeft + x.wealth,即在以x.left为根的子树中的最大Heritage加上x的wealth。其三是MaxHeritageOfRight + x.wealth,即在以x.right为根的子树中的最大Heritage加上x的wealth。
如此,通过递归后续遍历,可以解决此问题。
算法伪代码如下:
Input: Node x
Output:p, MaxHeritage , TreeWorth
function FindMaxHeritage(x)
(pOfLeft, MaxHeritageOfLeft , TreeWorthOfLeft) = FindMaxHeritage(x.left)
(pOfRight, MaxHeritageOfRight , TreeWorthOfRight) = FindMaxHeritage(x.right)
TreeWorth = TreeWorthOfLeft + TreeWorthOfRight + x.wealth
MaxHeritage = max{x.wealth - TreeWorthOfLeft - TreeWorthOfRight,
MaxHeritageOfLeft + x.wealth, MaxHeritageOfRight + x.wealth}
if MaxHeritage == x.wealth - TreeWorthOfLeft - TreeWorthOfRight then p=x
if MaxHeritage == MaxHeritageOfLeft + x.wealth then p=pOfLeft
if MaxHeritage == MaxHeritageOfRight + x.wealth then p=pOfRight
return (p, MaxHeritage, TreeWorth)
至此完。很有启发意义。