未通过所有测试用例的二叉树的最大路径
Posted
技术标签:
【中文标题】未通过所有测试用例的二叉树的最大路径【英文标题】:Maximum Path of a Binary tree not passing all the test cases 【发布时间】:2021-12-11 10:39:09 【问题描述】:我正在尝试解决这个 Leetcode 问题:Binary Tree Maximum Path Sum. 我知道这个问题有很多 SO 答案。但我找不到与我的问题相关的任何内容。因此,在深入研究代码之前,我想简要介绍一下我是如何编写算法的。
If I am at a particular node, I considered the following cases.
Case 1: The maximum path is somewhere inside the left subtree (not including the current node)
Case 2: The maximum path is somewhere inside the right subtree (not including the current node)
Case 3: The maximum path starts from the current node and ends somewhere in the left subtree
Case 4: The maximum path starts from the current node and ends somewhere in the right subtree
Case 5: The maximum path is the current node itself.
Case 6: The maximum path starts somewhere in the left subtree, goes through the current node, and ends somewhere in the right subtree.
这里是代码:
var maxPathSum = function(root)
if (root.left === null && root.right === null)
return root.val;
// Case 1: Max sum is in the left subtree (not including the root)
let leftPathSum = 0;
if (root.left)
leftPathSum = maxPathSum(root.left);
// Case 2: Max sum is in the right subtree (not including the root)
let rightPathSum = 0;
if (root.right)
rightPathSum = maxPathSum(root.right);
// Case 3: root + leftPathSum
let leftSumWithRoot = leftPathSum + root.val;
// Case 4: root + rightPathSum
let rightSumWithRoot = rightPathSum + root.val;
let maxWithRoot = Math.max(leftSumWithRoot, rightSumWithRoot);
let maxWithoutRoot = Math.max(leftPathSum, rightPathSum);
let maxSoFar = Math.max(maxWithRoot, maxWithoutRoot);
// Case 5: Root with alone
maxSoFar = Math.max(maxSoFar, root.val);
// Case 6: Max path goes through the root
let maxThroughRoot = leftSumWithRoot + rightSumWithRoot - root.val;
return Math.max(maxThroughRoot, maxSoFar);
;
我得到了一些测试用例通过,一些没有通过,尤其是那些具有负值的测试用例。我知道我的算法很可能有问题,但是有人可以帮我解决我的想法错误的方向。我看到了这个问题的不同解决方案。在某些解决方案中,他们将 maxPathSum(node.left) 和 maxPathSum(node.right) 与 0 进行比较,问题与此有关吗?此外,在其他一些解决方案中,他们没有考虑左右子树内的 maxPathSum。我不应该这样做吗?如果有人让我知道我在哪里做错了,我将非常感激。提前致谢。
【问题讨论】:
你看过失败的测试用例了吗?将代码粘贴到 Leetcode 中,失败的测试用例发生在树中的所有值都为负时,但您返回 0。想想如果所有树节点都有负值,答案应该是什么。 @kcsquared 你是对的。我想到了这一点,但不幸的是无法弄清楚如何处理 0 。另外,我写的案例有什么问题吗?你看到那里有什么问题吗?顺便说一句,谢谢你的回复。 案例没问题;在路径不能为空的问题中有一个未说明的假设。 @kcsquared 知道了。尽管我不确定我是否正确理解了它,但我会按照您的说法进行调查。再次感谢。 :-) 【参考方案1】:您的代码在此输入中失败:[-2,-1]
图表如下所示:
-2
/
-1
所以,let maxWithoutRoot = Math.max(leftPathSum, rightPathSum);
将是 0。然后 maxSoFar
将是零,所以最终你的输出是 0。如果我组织你的代码:
var maxPathSum = function(root)
let res=root.val
function dfs(node)
if (node===null)
return 0
let left=dfs(node.left)
let right=dfs(node.right)
// ignoring negatives. looking for max, so if left or right is negative, do not add it
let leftMax=Math.max(left,0)
let rightMax=Math.max(right,0)
res=Math.max(node.val+leftMax+rightMax,res)
return node.val+Math.max(leftMax,rightMax)
dfs(root)
return res
;
【讨论】:
感谢您的回复。我有个问题。为什么我们忽略左右子树上的负数?如果树只包含负数,我们将负值与 0 进行比较,我们将如何得到正确的结果?而在dfs函数中,为什么我们不直接返回res
呢?
@h_a 否定总是会减少总数。以上是关于未通过所有测试用例的二叉树的最大路径的主要内容,如果未能解决你的问题,请参考以下文章