2014-04-29 02:27

题目:找出10亿个数中最小的100万个数,假设内存可以装得下。

解法1:内存可以装得下?可以用快速选择算法得到无序的结果。时间复杂度总体是O(n)级别,但是常系数不小。

代码:

 // 18.6 Find the smallest one million number among one billion numbers.
// Suppose one billion numbers can fit in memory.
// I'll use quick selection algorithm to find them. This will return an unsorted result.
// Time complexity is O(n), but the constant factor may be massive. I don't quite like this algorithm.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std; const int CUT_OFF = ; int medianThree(vector<int> &v, int ll, int rr)
{
int mm = (ll + rr) / ; if (v[ll] > v[mm]) {
swap(v[ll], v[mm]);
}
if (v[ll] > v[rr]) {
swap(v[ll], v[rr]);
}
if (v[mm] > v[rr]) {
swap(v[mm], v[rr]);
}
swap(v[mm], v[rr - ]);
return v[rr - ];
} void quickSelect(vector<int> &v, int ll, int rr, int k)
{
// reference from "Data Structure and Algorithm Analysis in C" by Mark Allen Weiss.
int pivot;
int i, j; if (ll + CUT_OFF <= rr) {
pivot = medianThree(v, ll, rr);
i = ll;
j = rr - ; while (true) {
while (v[++i] < pivot);
while (v[--j] > pivot);
if (i > j) {
break;
}
swap(v[i], v[j]);
}
swap(v[i], v[rr - ]); if (k < i) {
return quickSelect(v, ll, i - , k);
} else if (k > i) {
return quickSelect(v, i + , rr, k);
}
} else {
for (i = ll; i <= rr; ++i) {
for (j = i + ; j <= rr; ++j) {
if (v[i] > v[j]) {
swap(v[i], v[j]);
}
}
}
}
} int main()
{
vector<int> v;
vector<int> res;
int n, k;
int i;
int k_small, count; while (cin >> n >> k && (n > && k > )) {
v.resize(n);
for (i = ; i < n; ++i) {
cin >> v[i];
} // find the kth smallest number
// this will change the order of elements
quickSelect(v, , n - , k - );
k_small = v[k - ];
count = k;
for (i = ; i < n; ++i) {
if (v[i] < k_small) {
--count;
}
}
for (i = ; i < n; ++i) {
if (v[i] < k_small) {
res.push_back(v[i]);
} else if (v[i] == k_small && count > ) {
res.push_back(v[i]);
--count;
}
} cout << '{';
for (i = ; i < k; ++i) {
i ? (cout << ' '), : ;
cout << res[i];
}
cout << '}' << endl; v.clear();
res.clear();
} return ;
}

解法2:如果要求结果也是有序的,那可以用最大堆得到有序结果。时间复杂度是O(n * log(m))级别,思路和代码相比快速选择算法都更简单,不过效率低了些。

代码:

 // 18.6 Find the smallest one million number among one billion numbers.
// Suppose one billion numbers can fit in memory.
// I'll use a max heap, which runs in O(n * log(k)) time, returns a sorted result.
#include <iostream>
#include <queue>
#include <vector>
using namespace std; template <class T>
struct myless {
bool operator () (const T &x, const T &y) {
return x < y;
};
}; int main()
{
int val;
int n, k;
int i;
// max heap
priority_queue<int, vector<int>, myless<int> > q;
vector<int> v; while (cin >> n >> k && (n > && k > )) {
k = k < n ? k : n;
for (i = ; i < k; ++i) {
cin >> val;
q.push(val);
} for (i = k; i < n; ++i) {
cin >> val;
if (q.top() > val) {
q.pop();
q.push(val);
}
}
while (!q.empty()) {
v.push_back(q.top());
q.pop();
}
reverse(v.begin(), v.end()); cout << '{';
for (i = ; i < k; ++i) {
i ? (cout << ' '), : ;
cout << v[i];
}
cout << '}' << endl; v.clear();
} return ;
}

《Cracking the Coding Interview》——第18章:难题——题目6的更多相关文章

  1. Cracking the coding interview 第一章问题及解答

    Cracking the coding interview 第一章问题及解答 不管是不是要挪地方,面试题具有很好的联系代码总用,参加新工作的半年里,做的大多是探索性的工作,反而代码写得少了,不高兴,最 ...

  2. 《Cracking the Coding Interview》读书笔记

    <Cracking the Coding Interview>是适合硅谷技术面试的一本面试指南,因为题目分类清晰,风格比较靠谱,所以广受推崇. 以下是我的读书笔记,基本都是每章的课后习题解 ...

  3. Cracking the coding interview

    写在开头 最近忙于论文的开题等工作,还有阿里的实习笔试,被虐的还行,说还行是因为自己的水平或者说是自己准备的还没有达到他们所需要人才的水平,所以就想找一本面试的书<Cracking the co ...

  4. Cracking the coding interview目录及资料收集

    前言 <Cracking the coding interview>是一本被许多人极力推荐的程序员面试书籍, 详情可见:http://www.careercup.com/book. 第六版 ...

  5. Cracking the Coding Interview(Trees and Graphs)

    Cracking the Coding Interview(Trees and Graphs) 树和图的训练平时相对很少,还是要加强训练一些树和图的基础算法.自己对树节点的设计应该不是很合理,多多少少 ...

  6. Cracking the Coding Interview(Stacks and Queues)

    Cracking the Coding Interview(Stacks and Queues) 1.Describe how you could use a single array to impl ...

  7. 二刷Cracking the Coding Interview(CC150第五版)

    第18章---高度难题 1,-------另类加法.实现加法. 另类加法 参与人数:327时间限制:3秒空间限制:32768K 算法知识视频讲解 题目描述 请编写一个函数,将两个数字相加.不得使用+或 ...

  8. 《Cracking the Coding Interview》——第18章:难题——题目13

    2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3 ...

  9. 《Cracking the Coding Interview》——第18章:难题——题目12

    2014-04-29 04:36 题目:最大子数组和的二位扩展:最大子矩阵和. 解法:一个维度上进行枚举,复杂度O(n^2):另一个维度执行最大子数组和算法,复杂度O(n).总体时间复杂度为O(n^3 ...

  10. 《Cracking the Coding Interview》——第18章:难题——题目11

    2014-04-29 04:30 题目:给定一个由‘0’或者‘1’构成的二维数组,找出一个四条边全部由‘1’构成的正方形(矩形中间可以有‘0’),使得矩形面积最大. 解法:用动态规划思想,记录二维数组 ...

随机推荐

  1. dotNetFx40_Client_x86_x64和dotNetFx40_Full_x86_x64这两个有什么区别?两个都要安装还是安装其中一个?

    这个是NET Framework 4.0的安装文件它是支持生成和运行下一代应用程序和 XML Web Services 的内部 Windows 组件,很多基于此架构的程序需要它的支持才能够运行.简单的 ...

  2. orderBy 过滤器

    orderBy 过滤器根据表达式排列数组: <!DOCTYPE html><html><head><meta http-equiv="Content ...

  3. django中介模型,CBV模型,及logging日志配制

    1.中介模型 中介模型,这个是在我们创建表格时,多对多添加的时候应用到的,通过制定ManyToManyField字段中的through参数来定义,为两者的关系新建一个中介class 为什么会产生这个中 ...

  4. 3.2.5 Magic Squares 魔板

    3.2.5 Magic Squares 魔板 成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方 ...

  5. SAP 文本框实例

    SAP 文本框 简单实例 REPORT ZTEST001. DATA: OK_CODE LIKE SY-UCOMM, SAVE_OK LIKE SY-UCOMM. DATA: REF_EDIT_CTN ...

  6. js匿名函数运行的方法

    Javascript中定义函数的方式有多种,函数直接量就是其中一种.如var fun = function(){},这里function如果不赋值给fun那么它就是一个匿名函数.好,看看匿名函数的如何 ...

  7. 项目配置中 提示access denied的问题 解决方案

    项目配置中 提示access denied的问题,一般原因是你的服务器或虚拟主机的pathinfo没开.... 具体解决办法如下 在PHP安装文件夹下找到php.ini.在文件中搜索cgi.fix_p ...

  8. php扩展开发-面向对象

    在zval变量里IS_OBJECT类型使用zend_object_value来保存变量的,我们看一下他的具体结果. typedef struct _zend_object_value { zend_o ...

  9. LINUX操作系统知识:进程与线程详解

    当一个程序开始执行后,在开始执行到执行完毕退出这段时间内,它在内存中的部分就叫称作一个进程. Linux 是一个多任务的操作系统,也就是说,在同一时间内,可以有多个进程同时执行.我们大家常用的单CPU ...

  10. 477. Total Hamming Distance

    class Solution { public: int totalHammingDistance(vector<int>& nums) { ; ; i < ; i++) { ...