【问题标题】:Big O notation in pythonpython中的大O符号
【发布时间】:2015-11-05 04:26:52
【问题描述】:

有没有人知道任何学习大符号的好资源?特别是学习如何浏览一些代码并能够看到它是 O(N^2) 还是 O(logN)?最好能告诉我为什么这样的代码等于 O(N log N)

def complex(numbers):
    N = len(numbers)
    result = 0
    for i in range(N):
        j = 1
        while j < N:
            result += numbers[i]*numbers[j]
            j = j*2
    return result 

谢谢!

【问题讨论】:

  • 这不是关于“代码”、“程序”或语言,而是关于算法。
  • @Porcelain 啊,好吧,但是你知道有什么好的网站可以提供帮助吗?有点像它的速成课程?
  • @JohnLaRooy 抱歉,O(N log N)

标签: python big-o notation


【解决方案1】:

首先,让我给你定义一下 O(N log N) 是什么。这意味着,程序最多将运行 N log N 操作,即它的上限为 ~N log N(其中 N 是输入的大小)。

现在,你的 N 是数字的大小,或者你的代码:

N = len(numbers)

请注意,第一个 for 循环从 0 运行到 N-1,总共进行了 N 次操作。这就是第一个 N 的来源。

-

那么,日志 N 是从哪里来的呢?它来自while循环。

在 while 循环中,你不断将 2 乘以 j,直到 j 大于或等于 N。

这将在我们执行循环 ~log2(N) 次后完成,它描述了我们必须将 j 乘以 2 的次数才能得到 N。例如 log2(8) = 3,因为我们相乘j 乘以 2 3 次得到 8:

#ofmult. j      oldj
  1      2  2 <- 1 * 2
  2      4  4 <- 2 * 2
  3      8  8 <- 4 * 2

为了更好地说明这一点,我在您的代码中添加了一个打印语句,用于 i 和 j:

def complex(numbers):
    N = len(numbers)
    result = 0
    for i in range(N):
        j = 1
        while j < N:
            print(str(i) + " " + str(j))
            result += numbers[i]*numbers[j]
            j = j*2
    return result 

运行时:

>>> complex([2,3,5,1,5,3,7,3])

这是输出的内容:

0 1
0 2
0 4
1 1
1 2
1 4
2 1
2 2
2 4
3 1
3 2
3 4
4 1
4 2
4 4
5 1
5 2
5 4
6 1
6 2
6 4
7 1
7 2
7 4

注意我们的 i 是如何从 0...7(总共 O(N) 的 N 次)开始的,第二部分,每个 i 总是有 3 ( log2(N) ) j 个输出。 所以,代码是 O(N log2 N)。

另外,我推荐的一些好的网站是: https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/

还有,来自斯坦福大学教授的系列讲座视频: https://www.youtube.com/watch?v=eNsKNfFUqFo

【讨论】:

  • 表示程序最多运行C乘以N log N,其中C是某个常数。
【解决方案2】:

当您将 j 乘以 2 时,您实际上是在说“我已经完成了剩下的问题的一半!”。在 while 循环的每一步,你都解决了剩下的问题的一半。因此,如果您的问题是x 大小,那么所需的迭代次数将是i = log_2 x,我们只是说是log x。在这种情况下,您的 x 正好等于 N。

for 循环让你重复上述部分 N 次,所以你得到 N * log N。

我们使用 O(N log N) 来表示,在每一步,我们可能会做任何 CONSTANT 数量的事情(例如在 while 循环中我可能会做十亿次操作),但我们并不关心这个常数,因为通常 N 通常更大,并且可以任意大(超出某个大小点,与 N 可能的值(即 googol)相比,即使是十亿也不算什么)。因此我们有 O(N log N)。

这是一个 pdf 格式的简短速成课程:

http://www1.icsi.berkeley.edu/~barath/cs61b-summer2002/lectures/lecture10.pdf

这是一个以讲座形式的简短速成课程:

https://www.youtube.com/watch?v=VIS4YDpuP98

【讨论】:

  • 截至 2019 年 3 月,两者都是死链接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多