先来解决二叉树节点间的最大距离问题。
最大距离来自以下几种可能:1. 左子树的最大距离lmax;
2. 右子树的最大距离rmax;
3. 左子树距根节点的最大距离maxFromLeft + 右子树距根节点的最大距离maxFromRight + 1;
于是,得出以下步骤:
①. 后续遍历整棵树, 对每棵子树执行②;
②. 设头节点为h,处理左子树,得到2个信息:lmax 和 maxFromLeft;处理右子树, 得到rmax 和maxFromRIght;
则 maxFromLeft + 1 + maxFromRight 是跨节点最大距离。将该值与lmax 和rmax 比较,得出的最大值即为 最大距离。
另,( maxFromLeft,maxFromRight)+ 1即为单边距离根节点h的最大距离。
public static int maxDistance(Node head) {
int[] record = new int[1];
return posOrder(head, record);
}
public static int posOrder(Node head, int[] record) {
if (head == null) {
record[0] = 0;
return 0;
}
int lMax = posOrder(head.left, record);
int maxfromLeft = record[0];
int rMax = posOrder(head.right, record);
int maxFromRight = record[0];
int curNodeMax = maxfromLeft + maxFromRight + 1;
record[0] = Math.max(maxfromLeft, maxFromRight) + 1;
return Math.max(Math.max(lMax, rMax), curNodeMax);
}
再来看最大路径和问题。和之前类似,最大路径和来自以下几种可能:
1. 左子树最大路径和lmax;
2. 右子树最大路径和rmax;
3. 根节点值root.val
4. 根节点和左右子树的结合
得出以下步骤:
① 后续遍历,设头节点为h,对每棵子树,执行步骤②;
② 遍历左子树,得出2个信息:子节点到根节点的最大路径和lToRootMax, 最大路径和lmax;
遍历右子树,得出2个信息:子节点到根节点的最大路径和RToRootMax, 最大路径和rmax
则跨节点最大路径和KMax = lToRootMax > 0 ? lToRootMax : 0
+ root.val
+ RToRootMax > 0 ? RToRootMax : 0;
最大路径和max = max{KMax, lmax, rmax}
public static int maxPathSum(TreeNode root){
int[] record = new int[1];
record[0] = Integer.MIN_VALUE;
posOrder(root, record);
return record[0];
}
public static int posOrder(TreeNode root, int[] record){
if(root == null)
return 0;
int LToRoot = posOrder(root.left, record);
int RToRoot = posOrder(root.right, record);
int curVal = (LToRoot > 0 ? LToRoot : 0) + root.val + (RToRoot > 0 ? RToRoot : 0);
record[0] = Math.max(record[0], curVal);
return Math.max(root.val, Math.max(root.val + LToRoot, root.val + RToRoot));
}