LeetCode 124.二叉树中的最大路径和

182 阅读2分钟

「这是我参与2022首次更文挑战的第39天,活动详情查看:2022首次更文挑战」。

题目:给定一颗二叉树的root节点,要求找到此二叉树中的最大路径和。最大路径和是指从二叉树的任意一个节点开始,到达另一个可到达节点的路径最大和。例如:

输入的root=[1, 2, 3],则最优路径为2 -> 1-> 3,最大路径和为6

解题思路

最大路径和无非就是由一个个节点组成,其可能的结果为:

  • 根节点
  • 左叶子节点
  • 右叶子节点
  • 左子树+根节点
  • 根节点+右子树
  • 左子树+根节点+右子树

我们可以先看树的一边,假设最左边子树只有三个节点,分别为1、2、3(左子树、根节点、右子树),那么对于子树1节点来说,其最大路径和就为1,对于子树2节点来说,其最大路径和为本身+左右子树,而对于右子树则也是其本身。由此子树递归至全树,即可得到如下代码:

int maxSum=Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
    dfs(root);
    return maxSum;
}

public int dfs(TreeNode root){
    if(root==null) return 0;
    int left = Math.max(dfs(root.left), 0);
    int right = Math.max(dfs(root.right), 0);
    maxSum = Math.max(maxSum, left+right+root.val);
    return Math.max(left, right) + root.val;
}

上述代码时间复杂度和空间复杂度都为O(N)O(N)

LeetCode上还有一题和本题思路相同,是LeetCode 543的求二叉树直径,其要求是计算二叉树可经过节点的最大路径。一颗树的最大直径是由这棵树的左子树和右子树的最大直径组成,因此可以对左右子树分别计算最大路径,并更新最大直径。需要注意的是,一颗子树的最大直径等于max(leftTree, rightTree) + 1,可得如下代码:

int max=0;
public int diameterOfBinaryTree(TreeNode root) {
    dfs(root);
    return max;
}

public int dfs(TreeNode root){
    if(root==null) return 0;
    int left=dfs(root.left);
    int right=dfs(root.right);
    max = Math.max(max,left+right);
    return Math.max(left, right)+1;
}

上述代码的时间复杂度和空间复杂度都是O(n)O(n)