124 二叉树中的最大路径和

124 二叉树中的最大路径和

Definition for a binary tree node.
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

参考代码

int ans = INT_MIN;
int oneSideMax(TreeNode* root) {
    if (root == nullptr) return 0;
    int left = max(0, oneSideMax(root->left));
    int right = max(0, oneSideMax(root->right));
    ans = max(ans, left + right + root->val);
    return max(left, right) + root->val;
}
class Solution {
    
    private int ret = Integer.MIN_VALUE;
    
    public int maxPathSum(TreeNode root) {
        /**
        对于任意一个节点, 如果最大和路径包含该节点, 那么只可能是两种情况:
        1. 其左右子树中所构成的和路径值较大的那个加上该节点的值后向父节点回溯构成最大路径
        2. 左右子树都在最大路径中, 加上该节点的值构成了最终的最大路径
        **/
        getMax(root);
        return ret;
    }
    
    private int getMax(TreeNode r) {
        if(r == null) return 0;
        int left = Math.max(0, getMax(r.left)); // 如果子树路径和为负则应当置0表示最大路径不包含子树
        int right = Math.max(0, getMax(r.right));
        ret = Math.max(ret, r.val + left + right); // 判断在该节点包含左右子树的路径和是否大于当前最大路径和
        return Math.max(left, right) + r.val;
    }
}

分析

自己想的分析 , 想到哪写到哪

二叉树的递归遍历 :

/* 基本的二叉树节点 */
class TreeNode {
    int val;
    TreeNode left, right;
}

resultType traverse(TreeNode root) {
    //退出条件
    if(){
        return;
    }
    traverse(root.left);
    traverse(root.right);
    //一般的返回情况
    return;
}

可以先走左边也可以先走右边 , 我们只讨论走左边的情况(走右边也是一样的)

到第一个退出条件时 , traverse(root.left) 后面的语句都还没执行 , 这句之前的语句已经运行了很多遍了 , 当前行一般也是没有运行的 , 所以我们可以在这条语句之前没有需要执行的语句时(中 / 后 序遍历) , 当做这个遍历是从此处开始的;

image-20210426212808783

运行到任意一个节点时 , 只有两种情况 :

  • 该节点在最长路径中

    又有两种情况 :

    • 该节点的较长路径子树和该节点自身加上该节点的回溯成最长路径
    • 该节点和两个子树连成最长路径
  • 该节点不在最长路径中

我们并不能在执行时断定此节点是否在最长路径中 , 所以我们需要记录这个节点的结果 , 然后在能确认此节点不是时替换该结果

原文地址:https://www.cnblogs.com/karlshuyuan/p/14706740.html