程序员面试题精选100题(57)-O(n)时间的排序[算法]
来源:互联网 发布:投资银行 知乎 编辑:程序博客网 时间:2024/06/01 07:55
题目:某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间。
分析:排序是面试时经常被提及的一类题目,我们也熟悉其中很多种算法,诸如插入排序、归并排序、冒泡排序,快速排序等等。这些排序的算法,要么是O(n2)的,要么是O(nlogn)的。可是这道题竟然要求是O(n)的,这里面到底有什么玄机呢?
题目特别强调是对一个公司的员工的年龄作排序。员工的数目虽然有几万人,但这几万员工的年龄却只有几十种可能。上班早的人一般也要等到将近二十岁才上班,一般人再晚到了六七十岁也不得不退休。
由于年龄总共只有几十种可能,我们可以很方便地统计出每一个年龄里有多少名员工。举个简单的例子,假设总共有5个员工,他们的年龄分别是25、24、26、24、25。我们统计出他们的年龄,24岁的有两个,25岁的也有两个,26岁的一个。那么我们根据年龄排序的结果就是:24、24、25、25、26,即在表示年龄的数组里写出两个24、两个25和一个26。
想明白了这种思路,我们就可以写出如下代码:
void SortAges(int ages[], int length){ if(ages == NULL || length <= 0) return; const int oldestAge = 99; int timesOfAge[oldestAge + 1]; for(int i = 0; i <= oldestAge; ++ i) timesOfAge[i] = 0; for(int i = 0; i < length; ++ i) { int age = ages[i]; if(age < 0 || age > oldestAge) throw new std::exception("age out of range."); ++ timesOfAge[age]; } int index = 0; for(int i = 0; i <= oldestAge; ++ i) { for(int j = 0; j < timesOfAge[i]; ++ j) { ages[index] = i; ++ index; } }}
在上面的代码中,允许的范围是0到99岁。数组timesOfAge用来统计每个年龄出现的次数。某个年龄出现了多少次,就在数组ages里设置几次该年龄。这样就相当于给数组ages排序了。该方法用长度100的整数数组辅助空间换来了O(n)的时间效率。由于不管对多少人的年龄作排序,辅助数组的长度是固定的100个整数,因此它的空间复杂度是个常数,即O(1)。
本文已经收录到《剑指Offer——名企面试官精讲典型编程题》一书中,有改动,书中的分析讲解更加详细。欢迎关注。
博主何海涛对本博客文章享有著作权。网络转载请注明出处http://zhedahht.blog.163.com/。整理出版物请和作者联系。对解题思路有任何建议,欢迎在评论中告知,或者加我微博http://weibo.com/zhedahht或者http://t.163.com/zhedahht与我讨论。谢谢。
- .程序员面试题精选100题(57)-O(n)时间的排序[算法]
- 程序员面试题精选100题(57)-O(n)时间的排序[算法]
- 程序员面试题精选100题(57)-O(n)时间的排序[算法]
- 程序员面试题精选100题(57)-O(n)时间的排序[算法]
- 程序员面试题精选100题(57)-O(n)时间的排序
- 程序员面试题精选100题(57)-O(n)时间的排序
- 程序员面试题精选100题(57)-O(n)时间的排序
- 程序员面试题精选100题(38)-输出1到最大的N位数[算法]
- 程序员面试题精选100题(43)-n个骰子的点数[算法]
- 程序员面试题精选100题(38)-输出1到最大的N位数[算法]
- 程序员面试题精选100题(38)-输出1到最大的N位数[算法]
- 程序员面试题精选100题(43)-n个骰子的点数[算法]
- 程序员面试题精选(55):如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点[数据结构]
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点[数据结构]
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点
- js点击子菜单折叠,再点击子菜单展开
- 成功程序员的8个习惯
- 计算机网络10--计算机网络体系结构简介
- Windows命令行创建计划任务
- Java并发编程:线程池的使用
- 程序员面试题精选100题(57)-O(n)时间的排序[算法]
- Mac利用brew安装nginx环境
- js实现灯泡的开和灭
- AngularJS 表达式 与 JavaScript 表达式
- 程序员面试题精选100题(58)-八皇后问题[算法]
- 程序员面试题精选100题(59)-字符串的组合[算法]
- Ionic+angularjs 环境配置及打包apk
- js下拉列表
- 程序员面试题精选100题(60)-判断二叉树是不是平衡[数据结构]