为什么leetcode215的时间复杂度是O(n)而二分查找的时间复杂度是O(logn)呢?

今天刷leetcode的时候有了一个关于时间复杂度的疑问。

leetcode215题是找第K大的数。

里面题解的partition方法的时间复杂度是O(n),怎么得出来的呢?

按照我的理解,时间复杂度就是程序运行次数的数量级。

第1次遍历了整个array,代码运行次数也就是n,
第2次遍历了1/2个array,代码运行次数是n/2,
第3次遍历了1/4个array,代码运行次数是n/4,
同理一直叠加,得到总执行次数为
n + n/2 + n/4 + n/8 +...+...
然而,
1/2 + 1/4 + 1/8 + 1/16 +...+... 趋近于 1
所以,
n + n/2 + n/4 + n/8 +...+...趋近于2n
省略掉常数之后,
就是O(n)

然而,二分查找好像跟这个也差不多,也是每次取一半来计算,那为什么时间复杂度却是O(logn)?

因为,二分查找中的数组是排好序的。
找到中间值的时间复杂度为O(1),而不用去遍历数组。
所以执行一次代码就能找到中间值。
执行一次代码后,剩下n/2个数,
执行两次代码后,剩下n/4个数,
执行三次代码后,剩下n/8个数,
...
执行k次代码后,剩下n/(2^k)个数。
在最坏的情况下,执行k次代码后,只剩下1个数。
这个数就是我们要找的数。
那么,在最坏的情况下,
n/(2^k) = 1
推出,
n = 2^k
可得,
k = log2(n)
省略掉常数之后即为,O(logn)

最后,由于这个跟快速排序强相关,下面顺便用这种思路来推导下,为什么快速排序的时间复杂度为O(nlogn)呢?

在快速排序中,
遍历1次数组后,代码的运行次数也就是n,能够使得1个数字在正确的位置上。
遍历2次数组后,代码的运行次数也就是2n,能够使得3个数字在正确的位置上。
遍历3次数组后,代码的运行次数也就是3n,能够使得7个数字在正确的位置上。
...
遍历k次数组后,代码的运行次数也就是kn,能够使得(2^k)-1个数字在正确的位置上。
我们的终极目的是,使得n个数字在正确的位置上,即为完成了排序。
那么,
(2^k)-1 = n
可推出,
2^k = n + 1
即,
k = log2(n+1)

由于代码的运行次数为kn,
所以可以得到,
kn = n * log2(n+1)
省略常数之后即为,O(nlogn)
author:xjnull
email:xjnull@gmail.com

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值