package tree;
/**
 * 二叉树中最大路径之和
 *
 * 路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
 *
 * 路径和 是路径中各节点值的总和。
 *
 * 给你一个二叉树的根节点 root ,返回其 最大路径和 。
 *
 * @author Tang
 *
 */
public class MaxPathSum {
    int max = 0;
    /**
     * 利用二叉树后序遍历
     * 利用递归 最优解思想
     * 从根结点开始,每次计算该节点的最大值 max(左子树+根节点, 右子树+根节点)
     *
     * @param root
     * @return
     */
    public int maxPathSum(TreeNode root) {
        if(root == null){
            return 0;
        }
        max = root.data;
        maxOnePath(root);
        return max;
    }
    /**
     * 某一个节点最大和
     * @param node
     * @return
     */
    private int maxOnePath(TreeNode node){
        if(node == null){
            return 0;
        }
        int left = node.data + maxOnePath(node.leftChild);
        int right = node.data + maxOnePath(node.rightChild);
        int value = node.data + maxOnePath(node.leftChild) + maxOnePath(node.rightChild);
        if(left > max){
            max = left;
        }
        if(right > max){
            max = right;
        }
        if(value > max){
            max = value;
        }
        return node.data + Math.max(maxOnePath(node.leftChild), maxOnePath(node.rightChild));
    }
    public static void main(String[] args) {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        node1.leftChild = node2;
        node1.rightChild = node3;
        node2.rightChild = node5;
        node2.leftChild = node4;
        node3.leftChild = node6;
        TreeNode root = node1;
        System.out.println(new MaxPathSum().maxPathSum(root));
    }
}