《Cracking the Coding Interview》——第18章:难题——题目6
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的更多相关文章
- Cracking the coding interview 第一章问题及解答
Cracking the coding interview 第一章问题及解答 不管是不是要挪地方,面试题具有很好的联系代码总用,参加新工作的半年里,做的大多是探索性的工作,反而代码写得少了,不高兴,最 ...
- 《Cracking the Coding Interview》读书笔记
<Cracking the Coding Interview>是适合硅谷技术面试的一本面试指南,因为题目分类清晰,风格比较靠谱,所以广受推崇. 以下是我的读书笔记,基本都是每章的课后习题解 ...
- Cracking the coding interview
写在开头 最近忙于论文的开题等工作,还有阿里的实习笔试,被虐的还行,说还行是因为自己的水平或者说是自己准备的还没有达到他们所需要人才的水平,所以就想找一本面试的书<Cracking the co ...
- Cracking the coding interview目录及资料收集
前言 <Cracking the coding interview>是一本被许多人极力推荐的程序员面试书籍, 详情可见:http://www.careercup.com/book. 第六版 ...
- Cracking the Coding Interview(Trees and Graphs)
Cracking the Coding Interview(Trees and Graphs) 树和图的训练平时相对很少,还是要加强训练一些树和图的基础算法.自己对树节点的设计应该不是很合理,多多少少 ...
- 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 ...
- 二刷Cracking the Coding Interview(CC150第五版)
第18章---高度难题 1,-------另类加法.实现加法. 另类加法 参与人数:327时间限制:3秒空间限制:32768K 算法知识视频讲解 题目描述 请编写一个函数,将两个数字相加.不得使用+或 ...
- 《Cracking the Coding Interview》——第18章:难题——题目13
2014-04-29 04:40 题目:给定一个字母组成的矩阵,和一个包含一堆单词的词典.请从矩阵中找出一个最大的子矩阵,使得从左到右每一行,从上到下每一列组成的单词都包含在词典中. 解法:O(n^3 ...
- 《Cracking the Coding Interview》——第18章:难题——题目12
2014-04-29 04:36 题目:最大子数组和的二位扩展:最大子矩阵和. 解法:一个维度上进行枚举,复杂度O(n^2):另一个维度执行最大子数组和算法,复杂度O(n).总体时间复杂度为O(n^3 ...
- 《Cracking the Coding Interview》——第18章:难题——题目11
2014-04-29 04:30 题目:给定一个由‘0’或者‘1’构成的二维数组,找出一个四条边全部由‘1’构成的正方形(矩形中间可以有‘0’),使得矩形面积最大. 解法:用动态规划思想,记录二维数组 ...
随机推荐
- 详细讲解:通过composer安装TP5.1(Thinkphp5.1)
现在TP5越来越火了,TP5也更新到了5.1版本,但是5.1以上版本只能通过composer来进行安装,那么这里贴出详细的步骤 前提:PHP版本必须要5.6以上 参考网址:http://www.thi ...
- zendstudio 汉化
http://archive.eclipse.org/technology/babel/index.php http://www.eclipse.org/babel/downloads.php 注册码 ...
- 【css基础修炼之路】— 谈谈元素的垂直水平居中
作为一个初级的前端工程师,在开发的过程中遇到了许多问题,其中使元素垂直居中这个问题难住了我,可能在大家看来这是一个非常小的问题,但是却困扰了我很长时间,于是决定做一个总结!!! 废话不多说,直接上代码 ...
- 如何使用事务码SMICM分析ABAP代码发起的HTTP请求的错误ICM_HTTP_SSL_PEER_CERT_UNTRUSTED
当我用CL_HTTP_CLIENT往一个外网的url发请求时,遇到错误:ICM_HTTP_SSL_PEER_CERT_UNTRUSTED 错误是从这段ABAP代码里抛出来的: CALL METHOD ...
- php5.5.15注释问题PHP Deprecated: Comments starting with '#' are deprecated in *.ini 警告解决办法
PHP Deprecated: Comments starting with '#' are deprecated in D:\mvam\php5\php.ini on line 1944 in U ...
- Android笔记(adb命令--reboot loader)
Android 的机器通过adb进入升级模式的方法 # adb shell # reboot loader 通过上面两个命令就进入升级模式了,通过工具升级就好了 为什么会写这简单的一篇呢?因为今天干了 ...
- Spring初始化Bean或销毁Bean前执行操作的方式
如果想在Spring初始化后,或者销毁前做某些操作,常用的设定方式有三种: 第一种:通过 在xml中定义init-method 和 destory-method方法 推荐使用,缺陷是只能在XML中使用 ...
- eclipse环境Dynamic web module version 3.1版本的进步,简化Dynamic web object 中Servlet类的配置,不用web.xml配置<Servlet>
eclipse环境Dynamic web module version 3.1版本之前,Dynamic web object 中Servlet类的配置,要在web.xml 配置<Servlet& ...
- 深入理解 SVG 系列(一) —— SVG 基础
来源:https://segmentfault.com/a/1190000015652209 本系列文章分为三个部分: 第一部分是 SVG 基础. 主要讲 SVG 的一些基础知识,包括 SVG 基本元 ...
- SVN中trunk,branches,tags用法详解(转载)
转载出处:http://www.cnblogs.com/dafozhang/archive/2012/06/28/2567769.html Subversion是一个自由开源的版本控制系统.在Subv ...