取最大值和最小值(常数级复杂度)
来源:互联网 发布:零基础学c语言看什么书 编辑:程序博客网 时间:2024/05/18 00:58
最近看到一篇博客登出了一道阿里的笔试题,关于最快的时间复杂度取出一个数组中的最大,以及最小值的问题,所以自己也就思考了下。大部分人的比较次数应该就是2N了。我想的这个算法思想,好像还有好一点,所以就贴出来,供大家看看。如果思路出问题了,烦请各位指出来。
给出示例数组:4 1 5 9 9 7 10 2 (N = 8)
思想大概是这样的:
1 . 比较1 和 N , 2 和 N-1 ...继续下去, 如果左边的比右边的大就互换。局部性上, 就会呈现左边的部分里必定有最小值,而右边的也绝对保存了最大值。
第一轮过后就成了: 2 1 5 9 ~ 9 7 10 4
2 . 在分开的左右部分中各自寻找最小值与最大值
第二轮过后就成了: 2 1 ~ 5 9 ~~4 7 ~ 9 10 (紫色为无需比较的部分)
3 . 这样左边部分又被划分成左边的左边部分, 右边的右边部分
第三轮过后就成了: 1 ~ 2 ~~ 5 9 ~~~ 4 7 ~~ 9 ~ 10
这样三轮过后就找出了最小值与最大值了。
数学分析比较次数(对于单边):
第1次比较的次数就是N/2^2 (数组比较长度为N/2, 再次对半)
.......
第n次比较的次数就是 N/2^k (N/2^k=1的)
N/2^k = 1 的最后一次比较。所以针对于左半边的次数就是
(N/2^2 + N/2^3 + ....+ N/2^k)
总的比较次数就是: N/2 + 2(N/2^2 +N/2^3 + .... + N/2^k) = 3N/2 - 2
时间复杂度为常数了!(正对于奇数个数组个数,只要在最后将数组的中间位和a[0] 或者 和 a[N-1]比较即可),
代码我就不写了,大伙有兴趣自己写写吧,不难。
算法流程:
如果是偶数个数的: 直接对半,比较即可,例如: 4 1 2 5 3 6 8 4 => 4 1 2 5 | 3 6 8 4
如果是奇数个数的: 先抛弃中间那个,再比较,例如: 4 1 2 5 3 6 8 4 10 => 4 1 2 5 | 3 | 6 8 4 10 最后再跟3比较下就好。
- 取最大值和最小值(常数级复杂度)
- Js取数组中最大值和最小值
- Js取数组中最大值和最小值
- 数组取最大值最小值
- 取最大值最小值
- sql取最大值、最小值
- java中给集合快速取值最大值和最小值
- 取数组最大值和最小值的方法汇总
- js 取数组最大值、最小值
- js 取数组最大值、最小值.
- JS取最小值/最大值排序
- 求最大值和最小值
- 求最大值和最小值
- 最大值和最小值Ex3
- 长度,最小值和最大值
- NYOJ-最大值和最小值
- NYOJ-最大值和最小值
- 最小值和最大值(9.1)
- Javascript实例教程:DOM方法创建和修改表格
- 批处理文件学习笔记
- Apache 和 Tomcat 简述(2)
- UITableView的常用属性
- eclipse tomcat 找不到 工程 解决方法~
- 取最大值和最小值(常数级复杂度)
- Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
- 自定义背景颜色的设置
- jquery操作select(取值,设置选中)
- Java 获取系统信息
- 番茄时间管理
- linux shell 下各种进制数据转换。
- Android各种访问权限Permission详解
- sharpdevelop源码学习