[CareerCup] 18.6 Smallest One Million Numbers 最小的一百万个数字
18.6 Describe an algorithm to find the smallest one million numbers in one billion numbers. Assume that the computer memory can hold all one billion numbers.
这道题让我们在十亿个数字中找到最小的一百万个数字,而且限定了计算机只有能存十亿个数字的内存。这题有三种解法,排序,最小堆,和选择排序。
首先来看排序方法,这种方法简单明了,就是把这十亿个数字按升序排列,然后返回前一百万个即可,时间复杂度是O(nlgn)。
然后来看最小堆做法,我们建立一个最大堆(大的数字在顶端),然后将前一百万个数字加进去。然后我们开始遍历剩下的数字,对于每一个数字,我们将其加入堆中,然后删掉堆中最大的数字。遍历接受后,我们就有了一百万个最小的数字,时间复杂度是O(nlgm),其中m是我们需要找的数字个数。
最后我们来看选择排序的方法,这种方法可以在线性时间内找到第i个最大或最小的数,如果数字都不是不同的,那么我们可以在O(n)的时间内找到第i个最小的数字,算法如下:
1. 随机选取数组中的一个数字当做pivot,然后以此来分割数组,记录分割处左边的数字的个数。
2. 如果左边正好有i个数字,那么返回左边最大的数字。
3. 如果左边数字个数大于i,那么继续在左边递归调用这个方法。
4. 如果左边数字个数小于i,那么在右边递归调用这个方法,但是此时的rank变为i - left_size。
参见代码如下:
int partition(vector<int> &array, int left, int right, int pivot) {
while (true) {
while (left <= right && array[left] <= pivot) ++left;
while (left <= right && array[right] > pivot) --right;
if (left >right) return left - ;
swap(array[left], array[right]);
}
}
int find_max(vector<int> &array, int left, int right) {
int res = INT_MIN;
for (int i = left; i <= right; ++i) {
res = max(res, array[i]);
}
return res;
}
int selection_rank(vector<int> &array, int left, int right, int rank) {
int pivot = array[rand() % (right - left + ) + left];
int left_end = partition(array, left, right, pivot);
int left_size = left_end - left + ;
if (left_size == rank + ) return find_max(array, left, left_end);
else if (rank < left_size) return selection_rank(array, left, left_end, rank);
else return selection_rank(array, left_end + , right, rank - left_size);
}
一旦找到了第i个最小的数字后,就可以遍历整个数组来找所有小于等于该数字的元素。当数组有重复元素的话,需要修改一些地方,但是时间就不能保证是线性的了。其实也有算法能线性时间内处理有重复的数组,但是比较复杂,有兴趣的请自行搜索研究。
[CareerCup] 18.6 Smallest One Million Numbers 最小的一百万个数字的更多相关文章
- [CareerCup] 18.1 Add Two Numbers 两数相加
18.1 Write a function that adds two numbers. You should not use + or any arithmetic operators. 这道题让我 ...
- [CareerCup] 18.9 Find and Maintain the Median Value 寻找和维护中位数
18.9 Numbers are randomly generated and passed to a method. Write a program to find and maintain the ...
- [LeetCode] Find K Pairs with Smallest Sums 找和最小的K对数字
You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Define ...
- [CareerCup] 18.12 Largest Sum Submatrix 和最大的子矩阵
18.12 Given an NxN matrix of positive and negative integers, write code to find the submatrix with t ...
- [CareerCup] 18.11 Maximum Subsquare 最大子方形
18.11 Imagine you have a square matrix, where each cell (pixel) is either black or white. Design an ...
- [CareerCup] 18.10 Word Transform 单词转换
18.10 Given two words of equal length that are in a dictionary, write a method to transform one word ...
- [CareerCup] 18.8 Search String 搜索字符串
18.8 Given a string s and an array of smaller strings T, design a method to search s for each small ...
- [CareerCup] 18.5 Shortest Distance between Two Words 两单词间的最短距离
18.5 You have a large text file containing words. Given any two words, find the shortest distance (i ...
- [CareerCup] 18.4 Count Number of Two 统计数字2的个数
18.4 Write a method to count the number of 2s between 0 and n. 这道题给了我们一个整数n,让我们求[0,n]区间内所有2出现的个数,比如如 ...
随机推荐
- Zigzag convert
public static String Convert(String s,int row) { char[] c=s.toCharArray(); int len=s.length(); Strin ...
- wpf textblock 会覆盖 button里面字体样式的解决方法 还有button的style覆盖。。datepicker里面的按钮的style
.(button使用contont写的时候) 当.button使用 <button.content><textBlock/></button.content>依然会 ...
- HDU 3341 Lost's revenge(AC自动机+DP)
Lost's revenge Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- zookeeper源码分析二FASTLEADER选举算法
如何在zookeeper集群中选举出一个leader,zookeeper使用了三种算法,具体使用哪种算法,在配置文件中是可以配置的,对应的配置项是"electionAlg",其中1 ...
- 战斗住的DPS才是DPS,持续的执行力才是执行力
工作久了,真的发现执行力这个东西太难被贯彻,计划时信心满满,冲劲十足,持续一段时间后就喇叭腔了.
- 金融左侧js错误
- kylin cube测试时,报错:org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, inode="/user":hdfs:supergroup:drwxr-xr-x
异常: org.apache.hadoop.security.AccessControlException: Permission denied: user=root, access=WRITE, i ...
- 【转】Spark性能优化指南——基础篇
http://mp.weixin.qq.com/s?__biz=MjM5NDMwNjMzNA==&mid=2651805828&idx=1&sn=2f413828d1fdc6a ...
- Notification
一:普通Notification 1.内容标题setContentTitle(...) 2.大图标setLargeIcon(Bitmap) 3.内容setContentText(...) 4.内容附加 ...
- Liferay 6.2 改造系列之二十三:修改Liferay原始主题中"技术支持:Liferay"字样
1.修改主题模板文件,具体位置如下 (1) portal-master\portal-web\docroot\html\themes\_unstyled\templates\portal_normal ...