《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’),使得矩形面积最大. 解法:用动态规划思想,记录二维数组 ...
随机推荐
- PointCNN 论文翻译解析
1. 前言 卷积神经网络在二维图像的应用已经较为成熟了,但 CNN 在三维空间上,尤其是点云这种无序集的应用现在研究得尤其少.山东大学近日公布的一项研究提出的 PointCNN 可以让 CNN 在点云 ...
- java中string类型转换成map
背景:有时候string类型的数据取出来是个很标准的key.value形式,通过Gson的可以直接转成map 使用方式: Gson gson = new Gson(); Map<String, ...
- POJ-3111 K Best---二分求最大化平均值
题目链接: https://cn.vjudge.net/problem/POJ-3111 题目大意: 卖宝救夫:Demy要卖珠宝,n件分别价值vi 重 wi,她希望保留k件使得 最大. 解题思路: # ...
- Poj(1789),最小生成树,Prim
题目链接:http://poj.org/problem?id=1789 还是套路. #include <stdio.h> #include <string.h> #define ...
- Spring boot 自动配置自定义配置文件
示例如下: 1. 新建 Maven 项目 properties 2. pom.xml <project xmlns="http://maven.apache.org/POM/4 ...
- 从Java官网下载JDK1.6等低版本JDK
今天在浏览Java官网的时候发现旧版本(1.8之前)的JDK安装包下载地址没有在下载页面明显的提供出来.个人通过在官网查看,发现oracle官方将旧版本的JDK全都放在Java Archive模块中了 ...
- 【PC-x86-x64】JDK 32bit与64bit的区别及x64 PC的发展历程【转】
一次偶然分析的机会: 在进行Minecraft也就是所谓的我的世界游戏的时候,在对局域网进行开放的时候,我的是64bit的JDK,而我同学的是32bit的JDK,所以在进行局域网链接的时候就会出现In ...
- 通过ServletContext取Spring的WebApplicationContext
当 Web 应用集成 Spring 容器后,代表 Spring 容器的 WebApplicationContext 对象将以WebApplicationContext.ROOT_WEB_APPLICA ...
- JS常见内置对象和方法
JS中常用的内置对象:Array对象.Date对象.正则表达式对象.string对象.Global对象 Array对象中常用方法: concat() 表示把几个数组合并成一个数组join() 设 ...
- 泉五培训Day4
T1 收果子 题目 [题目描述] 有一个果园,有n棵果树依次排成一排,其中已知第 i 棵果树上结了ai个果子.现在要按照果树编号顺序依次收果子,对于一个能装v个果树的果篮,收果子从第1棵果树开始,如果 ...