算法与数据结构
--引入
#找出符合a+b+c=1000 并且a^2 + b^2 = c^2的所有a、b、c的组合
#枚举法
import time
start_time = time.time()
for a in range(0,1001):
for b in range(0,1001):
for c in range(0,1001):
if a + b + c == 1000 and a**2 + b**2 == c**2:
print("a,b,c:%d,%d,%d" % (a,b,c))
print(time.time()-start_time)
print("finshed")
结果:
a,b,c:0,500,500
a,b,c:200,375,425
a,b,c:375,200,425
a,b,c:500,0,500
139.3686807155609
finshed
优化算法:
import time
start_time = time.time()
for a in range(0,1001):
for b in range(0,1001):
c = 1000 - a - b
if a**2 + b**2 == c**2:
print("a,b,c:%d,%d,%d" % (a,b,c))
print(time.time()-start_time)
print("finshed")
结果:
a,b,c:0,500,500
a,b,c:200,375,425
a,b,c:375,200,425
a,b,c:500,0,500
1.224724531173706
finshed
效果提升明显
每台机器执行的总时间不同,但是执行基本运算数量大体相同。
第一个方法的时间复杂度T1 = 1000*1000*1000 * 2
如果 a + b + c = N
T(n) = n*n*n*2 = n^3 *2(时间复杂度)
去掉系数则是大O表示法
大O记:
对于算法进行特别具体的细致分析虽然很好,但在实践中的实际价值有限。对于算法的时间性质和空间性质,
最重要的是其数量级和趋势,这些是分析算法效率的主要部分。而计量算法基本操作数量的规模函数中那些常量因子可以忽略不计。
例如,可以认为3n2和100n2属于同一个量级,如果两个算法处理同样规模实例的代价分别为这两个函数,就认为它们的效率“差不多”,都为n2级。
所以 第一个算法的大O表示法为T(n) = n^3
最坏时间复杂度:
无序列表
[1,3,2,,7,8,7....n] 排序这个列表的时间复杂度为n^2
有序列表
[1,2,3,4,5,6....n] 排序这个列表的时间复杂度为n
第一个为最坏时间复杂度
第二个为最优时间复杂度
算法完成工作最少需要多少基本操作,即最优时间复杂度
算法完成工作最多需要多少基本操作,即最坏时间复杂度
算法完成工作平均需要多少基本操作,即平均时间复杂度
对于最优时间复杂度,其价值不大,因为它没有提供什么有用信息,其反映的只是最乐观最理想的情况,没有参考价值。
对于最坏时间复杂度,提供了一种保证,表明算法在此种程度的基本操作中一定能完成工作。
时间复杂度的几条基本计算规则
1、基本操作,即只有常数项,认为其时间复杂度为O(1)
2、顺序结构,时间复杂度按加法进行计算
3、循环结构,时间复杂度按乘法进行计算
4、分支结构,时间复杂度取最大值
5、判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
6、在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
再看第二个算法的时间复杂度用大O表示法表示
T(n) = n*n*2 = O(n^2)
比较在空列表中插入元素的四种方法的时间复杂度
from timeit import Timer
def test1():
li = []
for i in range(10000):
li.append(i)
def test2():
li = []
for i in range(10000):
li += [i]
def test3():
li = [i for i in range(10000)]
def test4():
li = list(range(10000))
timer1 = Timer("test1()","from __main__ import test1")
print("test1:",timer1.timeit(1000))
timer2 = Timer("test2()","from __main__ import test2")
print("test2:",timer2.timeit(1000))
timer3 = Timer("test3()","from __main__ import test3")
print("test3",timer3.timeit(1000))
timer4 = Timer("test4()","from __main__ import test4")
print("test4",timer4.timeit(1000))
test1: 1.0213268933472477
test2: 0.9605182999694275
test3 0.4783739591189631
test4 0.2643097583689933