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. April 6 2017 Week 14 Thursday

    If you smile when no one else is around, you really mean it. 独处时的微笑,才是发自内心的. Recently I found I seld ...

  2. web前端的10个顶级CSS UI开源框架

    随着CSS3和HTML5的流行,我们的WEB页面不仅需要更人性化的设计理念,而且需要更酷的页面特效和用户体验.作为开发者,我们需要了解一些宝贵的CSS UI开源框架资源,它们可以帮助我们更快更好地实现 ...

  3. hdu-3449 Consumer---有依赖性质的背包

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3449 题目大意: fj打算去买一些东西,在那之前,他需要一些盒子去装他打算要买的不同的物品.每一个盒 ...

  4. http知识补充

    在我的职业生涯中,没怎么重视过这http四个字,想当然的觉得不就是个网页请求嘛就没怎么当回事,而且很多http相关的长篇大论一听就困,真心是弄不下去,但是就是这种观念导致我后期的工作中不断的挖坑,不断 ...

  5. 2018年第九届蓝桥杯【C++省赛B组】第三题 乘积尾零

    如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零?5650 4542 3554 473 946 4114 3871 9073 90 43292758 7949 6113 5659 ...

  6. 【洛谷P1314】[NOIP2011]聪明的质监员

    聪明的质监员 题目链接:https://www.luogu.org/problemnew/show/P1314 Y(W)随W的值增大而减小 二分W的值,找到最小的W使得Y(W)>S: 比较Y(W ...

  7. iOS第三方开放者平台概览

    前言:记录一些可能用到过的第三方开放者平台相关内容 视频类: 腾讯云移动直播:https://cloud.tencent.com/product/mlvb 遇到问题后发起工单是一种比较好的解决问题的方 ...

  8. Oracle中文乱码解决

    查看当前Oracle字符集 select userenv('language') from dual; USERENV('LANGUAGE') ---------------------------- ...

  9. IO流的应用_Copy文件

    IO流的应用_Copy文件 (1) import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...

  10. springMVC入门二

    一.准备工作 参考springMVC入门一,搭建maven项目如下: 前台结构如下: 项目介绍:使用springMVC实现前后台数据交互,例如controller返回json,页面传入pojo 二.具 ...