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. 安卓NDK流程

    定义wrap类,声明native函数,加载库 package com.ndk.hello; public class Classs { public native String say_hello() ...

  2. python 笔记1:官网下载及安装python;eclipse中安装配置pydev

    1  下载安装python. 官网:https://www.python.org/downloads/     根据自己的操作系统选择需要的版本下载并安装. 我的电脑操作系统windows xp的,只 ...

  3. win8下使用IIS服务器及自定义服务器端包含模块(SSI)步骤

    配置完过段时间就容易忘记,特此记录. 1.开启IIS服务器. 默认没有安装,需要先安装. 打开控制面板--> 打开“程序和功能”--> 左侧选择“启用或关闭windows功能”--> ...

  4. javascript当中的无限分类

    var data = [ {id:100000, name :"1", pid :0}, {id:100100, name :"1-1", pid :10000 ...

  5. SPOJ - LIS2 Another Longest Increasing Subsequence Problem

    cdq分治,dp(i)表示以i为结尾的最长LIS,那么dp的递推是依赖于左边的. 因此在分治的时候需要利用左边的子问题来递推右边. (345ms? 区间树TLE /****************** ...

  6. python web应用--web框架(三)

    了解了WSGI框架,我们发现:其实一个Web App,就是写一个WSGI的处理函数,针对每个HTTP请求进行响应. 但是如何处理HTTP请求不是问题,问题是如何处理100个不同的URL. 每一个URL ...

  7. 【洛谷P1063】NOIP2006能量项链

    能量项链 https://www.luogu.org/problemnew/show/P1063 好像比合并石子更水.. 区间动规,f[l][r]表示合并区间l~r的最大能量 按区间长度dp 枚举中间 ...

  8. 前端JavaScript之DOM节点操作

    1.HTML DOM是啥 Document Object Model:定义了访问和操作HTML文档的标准方法,把HTML文档呈现为带有元素,属性和文本的树状结构 2.解析过程 HTML加载完毕,渲染引 ...

  9. fastjson 应用

    fastjson优势就是解析快,用法和json-lib.jar差不多(如下图) 贴心的附上jar和反编译工具:https://pan.baidu.com/s/1iADAiFyoUZVBAFSPsIeY ...

  10. 破解weblogic(数据库)密码

    破解weblogic(数据库)密码所需步骤 注意:本例子本人以本地weblogic为列,必须已经安装weblogic 1.需要问题件 1>.数据源配置文件HKS***-****-jdbc.xml ...