[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出现的个数,比如如 ...
随机推荐
- poj 3468【线段树】
题意:给定Q(1<=Q<=100000)个数A1,A2…AQ,以及可能多次进行的两个操作 1)对某个区间Ai……Aj的每个数都加n(n可变) 2)对某个区间Ai……Aj的数求和 分析: 树 ...
- Chrome书签被篡改之后的恢复
chrome书签和备份存放的路径:(XXXX为用户名)(AppData文件夹为隐藏文件夹) \Users\XXXX\AppData\Local\Google\Chrome\User Data\Defa ...
- Jquery获取select,dropdownlist,checkbox下拉列表框的值
jQuery获取 Select选择的Text和Value: 语法解释: 1. $("#select_id").change(function(){//code...}); ...
- Base64编码保存到文件服务器
byte[] buffer = Convert.FromBase64String(param.Base64Code); System.Net.WebClient webClient = new Sys ...
- class.forname()用法 转
主要功能 Class.forName(xxx.xx.xx)返回的是一个类 Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类, 也就是说JVM会执行该类的静态代码段 ...
- 编解码-java序列化
大多数Java程序员接触到的第一种序列化或者编解码技术就是Java的默认序列化,只需要序列化的POJO对象实现java.io.Serializable接口,根据实际情况生成序列ID,这个类就能够通过j ...
- HTTP基础06--网络安全
HTTP 的缺点 通信使用明文可能会被窃听 HTTP 报文使用明文(指未经过加密的报文)方式发送. 通信的加密 用 SSL 建立安全通信线路之后,就可以在这条线路上进行 HTTP 通信了.与 SSL ...
- 10324 Global Warming dfs + 二分
时间限制:1000MS 内存限制:65535K提交次数:0 通过次数:0 题型: 编程题 语言: G++;GCC Description Global warming is a big prob ...
- BFS HDOJ 2102 A计划
题目传送门 题意:中文题面 分析:双层BFS,之前写过类似的题.总结坑点: 1.步数小于等于T都是YES 2. 传送门的另一侧还是传送门或者墙都会死 3. 走到传送门也需要一步 #include &l ...
- 疯狂java学习笔记之面向对象(一) - 定义类、方法、构造器
Java面向对象 1.定义类 2.创建对象.调用方法 类和对象: 某一类对象的概念定义. 比如:人类 - 抽象出来的概念(不特指某个人) 对象 - 在类的概念下产生的一个实例,它就是一个对象了. ja ...