一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
题目描述
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点 root ,返回其 最大路径和 。
思路分析
作为一道困难题,其实并没有很困难。 虽然题目给出了任意节点,以路径任意相连,但也代表对于一条路径,我们也可以理解为这条路径的最高父节点往左右的两条延伸(当然也可能只有一条)。
那么,如何计算一个节点左右延伸的最大值呢?
其实就是不断的递归就好,根据其左右子树的最大值+本身的value,当左右子树小于0时,排除。
具体实现
int maxPathSum(TreeNode* root) {
return dfs(root);
}
int dfs(TreeNode* node){
if (node == nullptr)return 0;
int val = node -> val;
int leftvalue = max(0, dfs(node->left));
int rightvalue = max(0, dfs(node -> right));
return max(max(max(0, val + leftvalue + rightvalue), leftvalue), rightvalue);
}
这么一写,发现不对
需要考虑其实全都是负数的场景。重新思考一下逻辑,我们现在是默认计算左右子树能贡献的最大值,也就是说,在这种计算中是可以允许左右子树均为0的。同时,根节点也默认必须被使用。
那么就会出现一个漏洞,就是比如我们的路径最后没有通过根节点,那这种最大值需要额外一个全局变量进行保存。
总结
思路写好了,就不再贴一次代码了。