【问题标题】:Calculating time complexity of this algorithm计算该算法的时间复杂度
【发布时间】:2021-08-25 10:40:36
【问题描述】:

所以我在 Leetcode 上做这个问题,在给定二叉树的中序和前序遍历的情况下,我们必须构建树。所以我编写了代码,并且解决方案正在运行,但是在计算解决方案的时间复杂度时我有点卡住了。有人可以提供计算它的见解吗?任何输入表示赞赏。代码如下:

class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
    def construct(preord, inord, noted):
        if preord == []:
            return

        root = TreeNode(preord[0])
        noted.add(preord[0])
        index = inord.index(preord.pop(0))
        
        for i in inord[index::-1]:
            if preord != [] and i == preord[0]:
                root.left = construct(preord, inord, noted)

        for i in inord[index + 1:]:
            if i in noted:
                break
            if preord != [] and i == preord[0]:
                root.right = construct(preord, inord, noted)
        return root
    
    visit = set()
    root = construct(preorder, inorder, visit)
    return root

【问题讨论】:

标签: algorithm recursion data-structures binary-tree tree-traversal


【解决方案1】:

变量声明和条件具有相同的时间复杂度:

O(1)
This means constant time

取决于您拥有的数据量的循环或其他语句:

O(N)

如果您有依赖数据的嵌套循环或再次声明:

O(n^k)

K being the number of nested levels you have.

这些不是唯一的,这是一个有用的链接,您可以在其中查看所有内容

https://www.bigocheatsheet.com/

根据您循环的元素数量或检查时间的增加或减少。当我们谈论时间复杂度时,我们需要始终把自己放在最坏的情况下。

假设您有 1000 个数字,并且您想检查例如 5 是否存在,您需要遍历所有数字并检查。

在最坏的情况下,您的程序可能需要检查所有这些,这就是为什么循环是 O(n),n 是您的 1000 个数字。

回到你的程序,你没有任何嵌套循环,但是你有一些 for 循环,所以你的算法的大 O 是 O(n)。

您不需要计算 if 或任何其他花费少于 O(n) 的语句。

class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
    def construct(preord, inord, noted):
        if preord == []:
            return

        root = TreeNode(preord[0])  //O(1) <--------------------
        noted.add(preord[0])
        index = inord.index(preord.pop(0))
        
        for i in inord[index::-1]:              //O(n) <-------------
            if preord != [] and i == preord[0]:
                root.left = construct(preord, inord, noted)

        for i in inord[index + 1:]:
            if i in noted:             //O(1) <---------------
                break
            if preord != [] and i == preord[0]:
                root.right = construct(preord, inord, noted)
        return root
    
    visit = set()
    root = construct(preorder, inorder, visit)
    return root

【讨论】:

  • 但是递归调用会影响运行时间复杂度吗?就像在 for 循环中一样,只要满足条件,就会调用构造函数。在最坏的情况下,它会被调用 n 次,那么这会以任何方式影响 O(n) 吗?
  • 递归时间复杂度的计算有点复杂。有两个定理可以帮助您,主定理和 Akra Bazzi 方法。您需要一定程度的数学才能理解它们,但如果您这样做,您将能够计算几乎所有递归算法的时间复杂度(有一些限制)。这是一篇关于大师定理的好文章yourbasic.org/algorithms/time-complexity-recursive-functions
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
  • 2018-10-15
相关资源
最近更新 更多