【问题标题】:Solution passes 37 test cases out of 39 but says 'Time Limit exceeded' for the rest解决方案通过了 39 个测试用例中的 37 个,但其余测试用例显示“超出时间限制”
【发布时间】:2021-06-26 17:02:34
【问题描述】:

我写了以下关于“二叉树的最大深度”的代码。它是一个递归解决方案。我获得了以下必须使用的模板:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """        

鉴于此模板,我的代码如下:

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """        
        if(not root):
            return 0
        return self.findDepth(root,1)  #self-defined function passing node and depth
        
    def findDepth(self,node,depth):
        
        if(node):
            '''if(node.left and not node.right):
            node=node.left
            if(node.right and not node.left):
            node=node.right'''
            if(node.left or node.right):
                depth=depth+1
            depth=self.findDepth(node.left,depth) if self.findDepth(node.left,depth)>self.findDepth(node.right,depth) else self.findDepth(node.right,depth)  #recursion after computing depth every time
        return depth
        

该解决方案适用于 37 个测试用例,但对于剩余的测试用例,我收到“超出时间限制”的错误。我用谷歌搜索并了解到它的发生是因为代码没有得到适当的优化或有一些不必要的循环/列表/数据结构。我没有使用任何未使用的数据结构,并且代码已尽可能优化。如何摆脱错误消息,以便代码可以在时限内尝试剩余的测试用例?提前致谢。

【问题讨论】:

  • 请提供预期的minimal, reproducible example (MRE)。我们应该能够复制和粘贴您的代码的连续块,执行该文件,并重现您的问题以及跟踪问题点的输出。这让我们可以根据您的测试数据和所需的输出来测试我们的建议。您发布的代码分为两块,没有驱动程序。不要指望我们输入测试数据,或者构建测试文件。相反,只需硬编码一个突出问题的测试用例。
  • 请注意,您基本上是在这里要求进行代码审查——这是一个不同的站点,StackExchange.CodeReview。然而,一个简单的调用跟踪可能在 Stack Overflow 的章程之内。完成您的 MRE。插入一些基本诊断,例如计数函数调用——您应该对树中的每个节点进行 一个 调用。那么您有一个具体的问题,我们可以解决您的问题。就目前而言,您让我们检查您的代码 - 正如发布指南告诉您的那样,“让其他人轻松帮助您。”
  • 将递归调用结果存储在一个变量中。您为每个节点遍历两个子树两次。这是很多的额外工作。这个三元太聪明了。

标签: python recursion tree binary-tree


【解决方案1】:

尽可能优化代码

远非如此,您拨打self.findDepth(...) 的频率是必要的两倍。此外,您强制执行一个您知道将失败的最终递归,只是为了返回depth 参数——if 比方法调用便宜。我期待更像(警告,未经测试的代码):

class Solution():
    def maxDepth(self, node):
        """
        :type node: TreeNode
        :rtype: int
        """

        depth = 0

        if node:
            left_depth = self.maxDepth(node.left) if node.left else 0
            right_depth = self.maxDepth(node.right) if node.right else 0

            depth = 1 + max(left_depth, right_depth)

        return depth

【讨论】:

  • 非常感谢您的解决方案。一个问题,你能解释一下我的代码中调用在哪里被执行了两倍吗?您的解决方案如何防止这种情况发生?
  • @QUEEN,正如其他人所指出的,问题在于 depth=self.findDepth(node.left,depth) if self.findDepth(node.left,depth)>self.findDepth(node.right,depth) else self.findDepth(node.right,depth) 的这个语句,其中 self.findDepth(node.left,depth) 的结果(以及“正确”)应该保存在局部变量中,而不是调用再次调用(再次,同上“正确”)。我的解决方案使用局部变量来避免重复调用。
  • 我其实不明白递归是如何在里面工作的。有人可以解释一下里面的递归堆栈以及变量值是如何相应变化的吗?
猜你喜欢
  • 2019-06-18
  • 1970-01-01
  • 2022-08-14
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
相关资源
最近更新 更多