力扣面试150题-- 二叉树中的最大路径和

Day 49

题目描述

力扣面试150题-- 二叉树中的最大路径和_第1张图片

思路

初次思路:采取两个递归函数的方式

  1. 第一个递归函数,采取后序遍历,判断从该某个点出发,先左走还是向右走所得的总和是最大的,将较大的那一边的值直接叠加在当前节点值上(这样做的目的,是筛选出该点的一半路径,同时加的那边一般是值较大的一边,这样第二个递归函数就能知道哪边没走了)
  2. 采取一个全局变量max,记录出现的路径总和最大值,第二个递归函数在第一个递归函数的基础上,前序遍历,判断每个节点是需要向没加的那一边走(取较小的一边),如果满足能走的条件(存在且不为负),就将当前节点的值加上另一边的值,与max比较,最后max得到的就是最大值。
    说明,两个递归函数中,第一个采取后序遍历是因为,我们的目的是找到每个节点那一边的最大值,因此是从下往上的,而第二个采取的是前序遍历,其实这个都无所谓了,因为我们第二个递归的目的只是遍历所有的节点即可
/**
 * 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;
 *     }
 * }
 */
class Solution {
    int max=-1001;
    public int change(TreeNode root){//第一个递归
        if(root==null){
            return 0;
        }
        if(root.left==null&&root.right==null){//叶子节点返回值
            return root.val;
        }
        int left=change(root.left);
        int right=change(root.right);//后序遍历
        if(right>=left&&right>0){//找到较大边且大于0
            root.val+=right;
        }
        else if(left>right&&left>0){
            root.val+=left;
        }
        else{//说明左右都是负的
            root.val=root.val;
        }
        return root.val;
    }
    public void findmax(TreeNode root){//第二个递归函数
        if(root==null){
            return;
        }
        if(root.left!=null&&root.right!=null){//左右孩子非空
            if(root.left.val>=root.right.val&&root.right.val>=0){//找到较小值并且大于0
                root.val+=root.right.val;
            }
            else if(root.right.val>root.left.val&&root.left.val>=0){
                 root.val+=root.left.val;
        }
            else{//两边都是负的
                root.val=root.val;
            }
        }
        else{//有一边为空,之前在第一次递归函数时已经加了
            root.val=root.val;
        }
        findmax(root.left);
        findmax(root.right);
        if(root.val>max){//更新返回值
            max=root.val;
        }
    }
    public int maxPathSum(TreeNode root) {
        //判断一个节点的左右的那边路径经过的值和最大,保存到该节点中
        change(root);
        //找到最大值
        findmax(root);
        return max;
    }
}

题解思路:感觉和我思路差不多,只是更加精炼一点

class Solution {
    int maxSum = Integer.MIN_VALUE;

    public int maxPathSum(TreeNode root) {
        maxGain(root);
        return maxSum;
    }

    public int maxGain(TreeNode node) {
        if (node == null) {
            return 0;
        }
        
        // 递归计算左右子节点的最大贡献值
        // 只有在最大贡献值大于 0 时,才会选取对应子节点
        int leftGain = Math.max(maxGain(node.left), 0);
        int rightGain = Math.max(maxGain(node.right), 0);

        // 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
        int priceNewpath = node.val + leftGain + rightGain;

        // 更新答案
        maxSum = Math.max(maxSum, priceNewpath);

        // 返回节点的最大贡献值
        return node.val + Math.max(leftGain, rightGain);
    }
}

你可能感兴趣的:(leetcode,面试,算法)