所以我不是CS专业,并且很难回答有关程序大(O)复杂性的问题。
我编写了以下例程来输出数组中的数字对,总和为0:
asd=[-3,-2,-3,2,3,2,4,5,8,-8,9,10,-4]
def sum_zero(asd):
for i in range(len(asd)):
for j in range(i,len(asd)):
if asd[i]+asd[j]==0:
print asd[i],asd[j]
现在,如果有人问这个方法的复杂性,我知道,因为第一个循环会彻底解决所有n
个项目(除非我错了),但有人可以解释如何找到正确的复杂性吗?
如果有更好的解决方法吗?
答案 0 :(得分:3)
我不会给你一个完整的解决方案,但会尽力指导你。
你应该拿一支铅笔和一张纸,然后问问自己:
语句print asd[i], asd[j]
执行了多少次? (在最坏的情况下,意味着你不应该真正关心那里的状况)
你会发现它真的取决于它上面的循环,它被执行len(asd)
(用n
表示)次。
你唯一需要知道的是,内部循环执行了多少次,外部循环有n
次迭代? (i
从0到n
)
如果您仍然不确定结果,只需采用真实的示例,比如n=20
,并计算执行最低语句的次数,这会给你一个非常好的关于答案的说明。
答案 1 :(得分:1)
def sum_zero(asd):
for i in range(len(asd)): # len called once = o(1), range called once = o(1)
for j in range(i,len(asd)): # len called once per i times = O(n), range called once per i times = O(n)
if asd[i]+asd[j]==0: # asd[i] called twice per j = o(2*n²)
# adding is called once per j = O(n²)
# comparing with 0 is called once per j = O(n²)
print asd[i],asd[j] # asd[i] is called twice per j = O(2*n²)
sum_zero(asd) # called once, o(1)
假设最坏的情况(if-condition
始终为真):
Total:
O(1) * 3
O(n) * 2
O(n²) * 6
O(6n² + 2n + 3)
一个展示复杂性的简单程序:
target= []
quadraditc = []
linear = []
for x in xrange(1,100):
linear.append(x)
target.append(6*(x**2) + 2*x + 3)
quadraditc.append(x**2)
import matplotlib.pyplot as plt
plt.plot(linear,label="Linear")
plt.plot(target,label="Target Function")
plt.plot(quadraditc,label="Quadratic")
plt.ylabel('Complexity')
plt.xlabel('Time')
plt.legend(loc=2)
plt.show()
正如@Micah Smith所指出的,上面的答案是最坏情况操作, Big-O实际上是O(n ^ 2),因为常数和低阶项被省略。