「这是我参与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;
}
上述代码时间复杂度和空间复杂度都为。
在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;
}
上述代码的时间复杂度和空间复杂度都是。