1. 题目
2. 分析
本题要求我们求二叉树的最大路径和,例如下图的15-20-7,就是该二叉树的最大路径;
2.1 路径
那么什么是路径呢?我的理解是只有能连成一条线,并且节点不重复的都是一条路径,例如,从9开始,有以下这些路径:
- 9
- 9 -10
- 9 -10 20
- 9 -10 20 15
- 9 -10 20 7
即:从某一个节点向上到某一个节点,然后向下
2.2 找最大路径
这么多路径,我们怎么去找到最大的那一条呢?
- 基于上面的结论,我们知道,一定有一个根,可能存在两个子节点
- 同时一个节点可以作为根节点、也可以作为子节点
- 如果用动态规划的思路:我们可以定义两个数组:以当前节点为根的最大值、以当前节点为子节点的最大值
- 递推公式分别是
- dpA[i] = dpB[l] + dpB[r] + num[i] (左右节点小于0的时候不加)
- dpB[i] = num[i] + max(dpB[l], dpB[r])(左右节点都小于0的时候不加)
- 遍历顺序可以采用递归的方式
3. 代码
int max = Integer.MIN_VALUE;
TreeNode treeNode = null;
public int maxPathSum(TreeNode root) {
if (null == treeNode) {
treeNode = root;
}
//动态规划
//以当前节点为子树的最大值
//以当前节点为根节点的最大值
//公式
//dpA[i] = dpB[l] + dpB[r] + num[i]
//dpB[i] = num[i] + max(dpB[l], dpB[r])
//边界值 null == 0
//遍历顺序:递归
if (null == root) {
return 0;
}
//左边节点作为子节点的最大值
int l = maxPathSum(root.left);
//右边节点作为子节点的最大值
int r = maxPathSum(root.right);
//当前节点作为子树最大值
int pathMax = root.val + Math.max(Math.max(l, r), 0);
//当前节点作为跟最大值
max = Math.max(max, root.val + Math.max(l, 0) + Math.max(r, 0));
if (treeNode == root) {
return max;
}
return pathMax;
}