网上的大多数答案都给出了如何找到树的直径,即如何找到最长路径中的节点数。
唯一的补充是我们需要存储对其有贡献的节点。
在递归中,这可以通过两种方式完成。
a) 它应该是一个返回类型
b) 它应该是一个输入参数,它是一个对象。该对象在递归过程中填充了结果。
不需要打印最长路径,我们只需要检查每个节点:
Max of
1) 左节点最大路径
2) 右节点最大路径
c) 当前节点最大路径(需要更多输入)
现在,要计算当前节点最大路径,我们需要更多输入:
当前节点最大路径需要:
1) 最大左节点高度
2) 最大右节点高度
这可以存储在节点本身中(作为高度参数),也可以通过递归传递。
这只会给出最长路径的直径/长度。
现在,要打印路径,我们需要存储更多信息,即:
-List<Nodes> pathList
这包含迄今为止形成最长路径的节点(注意这可能不包含当前节点)。
- List<Nodes> heightList
- 这包含形成从节点到其叶子的最长高度的节点。
最后是算法:
//方法的输入和输出
class Node{
int value;
Node leftchild;
Node rightchild;
}
class ReturnInfo{
ReturnInfo(){
maxpathlen = 0;
maxheight = 0;
pathList = new ArrayList<Node>();
heightList = new ArrayList<Node>();
}
int maxpathlen; //current max path
int maxheight; //current max height
List<Nodes> pathList;
List<Nodes> heightList;
}
//签名 public ReturnInfo getMaxPath(Node n);
//执行
public ReturnInfo getMaxPath(Node n){
//Base case
if(n==null) return new ReturnInfo();
//This is a bottom up recursion. Info will flow from leaves to root.
//So first recurse and then do the work at this node level
//Recurse left & right
ReturnInfo leftReturnInfo = getMaxPath(n.leftchild);
ReturnInfo rightReturnInfo = getMaxPath(n.rightchild);
//Do work in this recursion or for this node
ReturnInfo retInfo = new ReturnInfo();
//Update all 4 parameters of returninfo and we are done
retInfo.maxheight = max(leftReturnInfo.maxheight, rightReturnInfo.maxheight) + 1;
//Update retInfo.heightList accordingly
retInfo.heightList = ....
retInfo.maxPathLen = max(leftReturnInfo.maxPathLen, rigthReturnInfo.maxPathLen, leftReturnInfo.maxHeight+rightReturnInfo.maxHeight+1);
//Remember from where maxPathLen came from and update accordingly
retInfo.pathList = .....
return retInfo;//We are done
}