算法复杂度

接前面

反恐搜索——打印间隔两枚选择的硬币里一百个数据要一个小时还没有运行完成。它的复杂度是指数级的吗?

常见初等函数的变化曲线

在这里插入图片描述书中插图

T ( n ) = a ∗ T ( n / b ) + O ( n d ) T(n) = a*T(n/b)+O(n^d) T(n)=aT(n/b)+O(nd)

T ( n ) T(n) T(n) 代表递归方法处理规模为n的数据量的时间复杂度, a ∗ T ( n / b ) a*T(n/b) aT(n/b) 代表调用子递归方法的总体时间复杂度, O ( n d ) O(n^d) O(nd) 代表递归方法其他代码的时间复杂度。

a a a

a a a: 每次递归调用子问题的数量。即在一个递归方法,需要调用几次子递归方法。

b b b

b b b: 子问题的规模缩小的比例。例如二分法递归搜索时,每次需要查找的数据都缩小了一半,那么 b = 2 b=2 b=2

d d d

d d d: 每次递归调用之外的代码时间复杂度的参数。例如二分法递归搜索时,每次递归时除了调用递归的方法,没有什么for循环代码,时间复杂度是 O ( 1 ) O(1) O(1),即 n d = 1 n^d=1 nd=1,因此 $d=0%

推导

1、 d < log ⁡ b a d<\log_{b}a d<logba

递归时间复杂度为: O ( n log ⁡ b a ) O(n^{\log_{b}{a}}) O(nlogba)

2、 d = log ⁡ b a d=\log_{b}a d=logba

递归时间复杂度为: O ( n d ∗ log ⁡ n ) O(n^d *{\log_{}{n}}) O(ndlogn)

2、 d > log ⁡ b a d>\log_{b}a d>logba

递归时间复杂度为: O ( n d ) O(n^d) O(nd)

T ( n ) = 4 ∗ T ( n / 1.3 ) + O ( n 0 ) T(n) = 4*T(n/1.3)+O(n^0) T(n)=4T(n/1.3)+O(n0)

a = 4 a=4 a=4有四个递归调用,
b = 1.3 b=1.3 b=1.3原来一百的数量,最坏的跳过一个就是 100 99 \frac{100}{99} 99100,到最后最好是五个的时候跳过四个 5 1 \frac{5}{1} 15,取两个的中值1.3吧。
d = 0 d=0 d=0 max是调用的Python,几乎常数级别。
log ⁡ 1.3 4 = 5.283853591622281 \log_{1.3}4=5.283853591622281 log1.34=5.283853591622281
10 0 5.283853591622281 = 36957891253.5873 100^{5.283853591622281}=36957891253.5873 1005.283853591622281=36957891253.5873

与20个数字对比

20个算出的复杂度是7489486.036335511,100个数字的复杂度是它的4934.636512343405倍。测试20个用时0.42999982833862305秒。

s=time.time()
row = [552, 440, 606, 818, 756, 577, 266, 312, 174, 692, 492, 635, 92, 644, 571, 51, 732, 357, 110, 545]    
_, table = coins2(row,{})
print(time.time()-s)
0.42999982833862305
{0: 0, 1: 545, 2: 655, 3: 655, 4: 1277, 5: 1328, 6: 1328, 7: 1921, 8: 2013, 9: 2055, 10: 2455, 11: 3105, 12: 3105, 13: 3105, 14: 3371, 15: 3948, 16: 4438, 17: 4679, 18: 4795, 19: 4994, 20: 5430}

这样看一个小时应该会有答案。是不是问题的缩小规模没有那么大?

1.1

从5次方变成了14次方。

>>> import math
>>> math.log(4,1.1)
14.545081794683426
>>> 

那就是20个数字用时的13647875839.232113倍,要186年完成计算。

>>> 0.42999982833862305*13647875839.232113/(3600*24*365)
186.0915863792697

指数级的复杂度

从开头的图也可以看出3次方的时候就直接竖上去了。20以内的数据量还可以承受的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值