【问题标题】:Time and Space analysis in python [closed]python中的时间和空间分析[关闭]
【发布时间】:2019-11-30 07:33:41
【问题描述】:

谁能提供一个关于时间和空间的 O(log(n)) 和 O(nlog(n)) 问题的例子?

我对这种类型的分析很陌生,看不到过去的多项式时间/空间。

我不明白你怎么会是 O(1) O(log(n))

此外,我将不胜感激任何涵盖这些情况(时间和空间)的优秀示例:

我发现空间分析有点模棱两可,因此与同一地点的时间分析中的其他案例相比,很高兴看到它 - 我无法在网上找到可靠的东西。

你能提供每个案例在空间和时间上的例子吗 分析?

【问题讨论】:

    标签: python python-3.x performance time-complexity space-complexity


    【解决方案1】:

    在示例之前,对大 O 表示法的一点说明

    也许我看错了,但是看到

    我不明白的是,你怎么能成为 O(1)

    让我觉得您已经了解了 big-O 表示法的概念,即要进行的操作数(或要存储的字节数等),例如如果您有一个循环for(int i=0;i<n;++i) 然后有n 操作,所以时间复杂度是O(n)。虽然这是一个很好的第一直觉,但我认为它可能会产生误导,因为大 O 表示法定义了更高的渐近界。

    假设您选择了一种算法来对数字数组进行排序,我们将x 表示该数组中元素的数量,并将f(x) 表示该算法的时间复杂度。现在假设我们说算法是O(g(x))。这意味着随着x 的增长,我们最终将达到一个阈值x_t,这样如果x_i>x_t,那么abs(f(x_i)) 将始终低于或等于alpha*g(x_i),其中alpha 是一个postivie 实数.

    因此,O(1) 的函数并不总是花费相同的常数时间,相反,您可以确定无论它需要多少数据,完成任务所需的时间都是低于固定时间,例如 5seconds。同样,O(log(n)) 并不意味着有任何半常数的概念。这只是意味着 1) 算法所花费的时间将取决于您提供给它的数据集的大小,以及 2) 如果数据集足够大( n 足够大),那么它完成所需的时间总是小于或等于log(n)

    一些关于时间复杂度的例子

    • O(1):访问数组中的元素。
    • O(log(n))binary search 在增量排序的数组中。假设您有一个由n 元素组成的数组,并且您想要找到值等于x 的索引。你可以从数组的中间开始,如果你读到的值v大于x,你在v的左边重复同样的过程,如果它更小,你看看v 的右侧。您继续此过程,直到找到您要查找的值。如您所见,如果幸运的话,您可以在第一次尝试时找到数组中间的值,也可以在log(n) 操作后找到它。所以不存在半常数,Big-O 表示法会告诉您最坏的情况。
    • O(nlogn):使用Heap sort 对数组进行排序。在这里解释有点太长了。
    • O(n^2):计算正方形灰度图像上所有像素的总和(您可以将其视为二维数字矩阵)。
    • O(n^3):天真地将两个大小为 n*n 的矩阵相乘。
    • O(n^{2+epsilon}):以智能方式乘法矩阵 (see wikipedia)
    • O(n!) 天真地计算阶乘。

    一些关于空间复杂度的例子

    • O(1)堆排序。有人可能会认为,由于您需要从树的根中删除变量,因此您将需要额外的空间。但是,由于堆可以仅实现为数组,因此您可以将删除的值存储在所述数组的末尾,而不是分配新空间。
    • 我认为,一个有趣的例子是比较经典问题的两个解决方案:假设您有一个整数数组 X 和一个目标值 T,并且您得到保证存在两个在X 中的值x,y 使得x+y==T。您的目标是找到这两个值。 一种解决方案(称为双指针)是使用堆排序(O(1) 空格)对数组进行排序,然后定义两个索引i,j,它们分别指向排序数组X_sorted 的开始和结束。然后,如果X[i]+X[j]<T,我们增加i,如果X[i]+X[j]>T,我们减少j。当X[i]+X[j]==T 时我们停止。很明显,这不需要额外的分配,因此该解决方案具有O(1) 空间复杂度。第二种解决方案是:

      D={}
      for i in range(len(X)):
          D[T-X[i]]=i
      for x in X:
          y=T-x
          if y in D:
              return X[D[y]],x
      

      由于字典,空间复杂度O(n)

    上面给出的时间复杂度示例(除了关于有效矩阵乘法的示例)非常简单。正如其他人所说,我认为阅读有关该主题的书是深入理解该主题的最佳选择。我强烈推荐Cormen's book

    【讨论】:

      【解决方案2】:

      这是一个相当简单的答案:无论你有什么公式 f(n),以下算法分别在 O(f(n)) 时间和空间中运行,只要f 本身的计算速度不会太慢。

      def meaningless_waste_of_time(n):
          m = f(n)
          for i in range(int(m)):
              print('foo')
      
      def meaningless_waste_of_space(n):
          m = f(n)
          lst = []
          for i in range(int(m)):
              lst.append('bar')
      

      例如,如果您定义f = lambda n: (n ** 2) * math.log(n),那么时间和空间复杂度将分别为 O(n² log n)。

      【讨论】:

      • 我认为这只适用于f(n) 是一个整数...如果它是n^{2.15} 怎么办?不过仍然是一个聪明的答案。
      • @Ash 好电话,我已编辑为在输出中使用int
      【解决方案3】:

      首先我想指出一个事实,我们发现Time ComplexitySpace Complexity 是一种算法,而不是一种编程语言。如果您考虑计算任何程序的时间复杂度,我只能建议您选择C。在python中计算Time Complexity在技术上是非常困难的。

      示例:
      假设您正在创建一个列表并在 for 循环的每次传递中对其进行排序,就像这样

      n = int(input())
      
      for i in range(n):
          l.append(int(input())
          l = sorted(l)
      

      在这里,乍一看,我们的直觉是它的时间复杂度为 O(n),但仔细研究后,我们会注意到 sorted() 函数正在被调用,众所周知,任何排序算法不能小于O(n log n)(除了基数和计数排序有O(kn)O(n+k)时间复杂度),所以这段代码的最小时间复杂度为O(n^2 log n)

      有了这个,我建议你阅读一些好的Data Structure and Algorithm 书以便更好地理解。你可以去找一本 B. Tech 或 B.E. 规定的书。课程。希望这对你有帮助:)

      【讨论】:

        最近更新 更多