【问题标题】:Understanding how to measure the time complexity of a function了解如何测量函数的时间复杂度
【发布时间】:2018-06-18 01:57:43
【问题描述】:

这是函数:

c = []
def badsort(l):
  v = 0
  m = len(l)
  while v<m:
    c.append(min(l))
    l.remove(min(l))
    v+=1
  return c

虽然我意识到这是一种非常低效的排序方式,但我想知道这样一个函数的时间复杂度是多少,因为虽然它没有嵌套循环,但它会重复循环多次。

【问题讨论】:

  • 如果它说“坏”,它几乎总是二次或更糟。

标签: python performance big-o


【解决方案1】:

术语

假设n = len(l)

迭代次数

外部循环运行 n 次。内部循环中的 min() 在 l 上运行两次(此处有优化空间),但对于递增的数字(对于循环的每次迭代, l 的长度都会减少,因为您每次都从列表中删除一个项目)。

这样复杂度是2 * (n + (n-1) + (n-2) + ... + (n-n))。 这等于2 * (n^2 - (1 + 2 + 3 + ... + n))。 括号中的第二项是triangular number 并分歧为n*(n+1)/2

因此,您的复杂度等于2*(n^2 - n*(n+1)/2))。 这可以扩展为2*(n^2 - n^2/2 - n/2), 并简化为n^2 - n

BigO 表示法

BigO 表示法对整体增长趋势感兴趣,而不是函数的精确增长率。​​p>

删除常量

在 BigO 表示法中,常量被删除。这让我们仍然使用n^2 - n,因为没有常量。

仅保留主导词

此外,在 BigO 表示法中,仅考虑主要术语。 n^2n 占主导地位,所以 n 被删除。

结果

这意味着 BigO 中的答案是 O(n) = n^2,即二次复杂度。

【讨论】:

    【解决方案2】:

    这里有几个有用的点可以帮助您了解如何找出函数的复杂性。

    1. 测量迭代次数
    2. 在每次迭代中测量每个操作的复杂性

    对于第一点,您看到终止条件是v &lt; m,其中v 最初为0,m 是列表的大小。由于v 在每次迭代中递增一,因此循环最多(至少)运行N 次,其中N 是列表的大小。

    现在,关于第二点。每次迭代我们都有 -

    c.append(min(l))
    

    其中min 是一个线性运算,占用O(N) 时间。 append 是一个常量操作。

    接下来,

    l.remove(min(l))
    

    同样,min 是线性的,remove 也是如此。所以,你有O(N) + O(N) 这是O(N)

    总之,您有O(N) 迭代,每次迭代都有O(N),使其成为O(N ** 2),或二次。

    【讨论】:

    • @RoadRunner 政治、复仇投票等。天空是极限 ;-)
    【解决方案3】:

    这个问题的时间复杂度是O(n^2)。虽然代码本身只有一个明显的循环,while 循环,minmax 函数在实现上都是O(n),因为在最坏的情况下,它必须扫描整个列表才能找到对应的最小值或最大值。 list.removeO(n) 因为它也必须遍历列表,直到找到第一个目标值,在最坏的情况下,它可能在最后。 list.append摊销 O(1),由于该方法的巧妙实现,因为list.append 在技术上是O(n)/n = O(1) 用于n 推送的对象:

    def badsort(l):
      v = 0
      m = len(l)
      while v<m: #O(n)
        c.append(min(l)) #O(n) + O(1) 
        l.remove(min(l)) #O(n) + O(n)
        v+=1
      return c
    

    因此,有:

    Outer(O(n)) * Inner(O(n)+O(n)+O(n)) = Outer(O(n)) * Inner(O(n))
    

    O(n)+O(n)+O(n) 可以简单地组合成O(n),因为大 o 表示最坏的情况。因此,通过结合外部和内部复杂度,最终的复杂度为O(n^2)

    【讨论】:

    • 你应该解释为什么这些行是 O(N),以及具体是什么促成了它。
    • 在最后一行中,您提到最终复杂度是 O(n),但在第一行中,您提到了 O(n^2)。总体时间复杂度是多少?
    • 好的。这太棒了。谢谢!
    • 你不应该将内部和外部的时间复杂度相乘而不是相加吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 2020-11-06
    相关资源
    最近更新 更多