leetcode124. 二叉树中的最大路径和
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
看到这题一开始整体的思路还是递归,对左右子树分别递归处理。如果dfs(root)表示以root为根的子树的最长路径和,dfs(left), dfs(right)分别表示左右子树的最长路径和,那么dfs(root)与dfs(left), dfs(right)的关系共有下面6种情况:
- dfs(root) = root->val //只取根节点
- dfs(root) = dfs(left) //只取左子树
- dfs(root) = dfs(right) //只取右子树
- dfs(root) = root->val + dfs(left) //取根节点和左子树
- dfs(root) = root->val + dfs(right) //取根节点和右子树
- dfs(root) = root->val + dfs(left) + dfs(right) //取根节点和左子树
但这样存在一个很明显的问题,如果左/右子树的最长路径和不包括root的左/右子节点,那么最长路径和root就不是连接的,这样2-6这5种情况都是有问题的。为了解决这个问题,我们对dfs(root)的假设进行加强,令 dfs(root)表示以root为根且经过root的最长路径长度,这样root和dfs(left)/dfs(right)就一定是连接上的。注意此时2,3种情况必须舍去了,因为更新后的值没有经过root,不符合dfs(root)的定义,dfs(root)对应下面4种情况。此外,由于dfs(root)的意思变了,为以root为根经过root的最长,最后dfs(root)不一定是全局的最长路径长度,因此需要一个全局变量maxlen记录最长路径长度,在每次递归时更新maxlen。
同时,对于情况6,是不能出现在递归条件中的,因为如果用6更新dfs(root),会导致root出现左右分支,这种情况是不可以把dfs(root)继续提交给父节点,作为父节点的一个子结构处理的,但是可以作为最大值的一个可能结果。
代码实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
int maxsum = 0x80000000;
public:
int maxPathSum(TreeNode* root) {
dfs(root);
return maxsum;
}
// 返回以root为根,经过root的最大和
int dfs(TreeNode* root)
{
if (root==NULL)
return 0;
int leftmax = dfs(root->left);
int rightmax = dfs(root->right);
int sum = root->val;
sum = max(sum, root->val+leftmax);
sum = max(sum, root->val+rightmax);
sum = max(sum, root->val+leftmax+rightmax);
maxsum = max(maxsum, sum);
return root->val + max({0, leftmax, rightmax});
}
};
leetcode543.二叉树的直径
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。
这道题和上面一道题的思路基本一致
如果depth(root)表示以root为根且经过root的子树的最长直径,depth(left), depth(right)分别表示左右子树的结果,那么depth(root)的情况有下面种:
- depth(root) = 1 + depth(left) //取root和左子树
- depth(root) = 1 + depth(right) //取root和右子树
- depth(root) = depth(left) + depth(right) //取root和左右子树
同样,第3种情况不能作为递归条件。
代码实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
int ans=0;
public:
int diameterOfBinaryTree(TreeNode* root) {
depth(root);
return ans;
}
int depth(TreeNode* root)
{
if (!root) return 0;
int l = depth(root->left);
int r = depth(root->right);
ans = max(ans, l+r);
return 1+max(l, r);
}
};
题目
https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/
https://leetcode-cn.com/problems/diameter-of-binary-tree/