有没有人知道学习大写法的任何好资源?特别是学习如何遍历一些代码并能够看到它是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
谢谢!
答案 0 :(得分:1)
首先,让我向你定义O(N log N)是什么。这意味着程序将在大多数N log N操作中运行,即它具有~N log N的上限(其中N是输入的大小)。
现在,您的N是数字或代码的大小:
N = len(numbers)
请注意,第一个for循环从0运行到N-1,总计N个操作。这是第一个N来自的地方。
-
然后,log N来自哪里?它来自while循环。
在while循环中,您将2乘以j直到j大于或等于N.
当我们执行loop~log2(N)次时,这将完成,它描述了我们必须将j乘以2到达N的次数。例如,log2(8)= 3,因为我们乘以j乘2三次得到8:
#ofmult. j oldj
1 2 2 <- 1 * 2
2 4 4 <- 2 * 2
3 8 8 <- 4 * 2
为了更好地说明这一点,我在你的代码中为i和j添加了一个print语句:
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
答案 1 :(得分:0)
当你将j乘以2时,你实际上是在说“我已经完成了剩余问题的一半!”。在while循环的每一步,你解决了剩下的一半问题。因此,如果您的问题大小为x
,则所需的迭代次数为i = log_2 x
,我们只是说log x
。在这种情况下,你的x只等于N.
for循环让你再次执行上面的N次,所以得到N * log N。
我们使用O(N log N)来表示,在每一步,我们可能会做任何常数的事情(例如在while循环中我可能会进行十亿次操作),但我们并不关心这个恒定,因为通常N通常更大,并且可以任意大(超过一定大小的点,甚至十亿也没有什么比N可能是什么,即googol)。因此我们有O(N log N)。
这是一个pdf形式的简短速成课程:
http://www1.icsi.berkeley.edu/~barath/cs61b-summer2002/lectures/lecture10.pdf
这是一个讲座形式的简短速成课程: