《Cracking the Coding Interview》——第18章:难题——题目6
2014-04-29 03:05
357 查看
2014-04-29 02:27
题目:找出10亿个数中最小的100万个数,假设内存可以装得下。
解法1:内存可以装得下?可以用快速选择算法得到无序的结果。时间复杂度总体是O(n)级别,但是常系数不小。
代码:
解法2:如果要求结果也是有序的,那可以用最大堆得到有序结果。时间复杂度是O(n * log(m))级别,思路和代码相比快速选择算法都更简单,不过效率低了些。
代码:
题目:找出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 = 3; int medianThree(vector<int> &v, int ll, int rr) { int mm = (ll + rr) / 2; 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 - 1]); return v[rr - 1]; } 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 - 1; while (true) { while (v[++i] < pivot); while (v[--j] > pivot); if (i > j) { break; } swap(v[i], v[j]); } swap(v[i], v[rr - 1]); if (k < i) { return quickSelect(v, ll, i - 1, k); } else if (k > i) { return quickSelect(v, i + 1, rr, k); } } else { for (i = ll; i <= rr; ++i) { for (j = i + 1; 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 > 0 && k > 0)) { v.resize(n); for (i = 0; i < n; ++i) { cin >> v[i]; } // find the kth smallest number // this will change the order of elements quickSelect(v, 0, n - 1, k - 1); k_small = v[k - 1]; count = k; for (i = 0; i < n; ++i) { if (v[i] < k_small) { --count; } } for (i = 0; i < n; ++i) { if (v[i] < k_small) { res.push_back(v[i]); } else if (v[i] == k_small && count > 0) { res.push_back(v[i]); --count; } } cout << '{'; for (i = 0; i < k; ++i) { i ? (cout << ' '), 1 : 1; cout << res[i]; } cout << '}' << endl; v.clear(); res.clear(); } return 0; }
解法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 > 0 && k > 0)) { k = k < n ? k : n; for (i = 0; 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 = 0; i < k; ++i) { i ? (cout << ' '), 1 : 1; cout << v[i]; } cout << '}' << endl; v.clear(); } return 0; }
相关文章推荐
- 《Cracking the Coding Interview》——第18章:难题——题目10
- 《Cracking the Coding Interview》——第18章:难题——题目11
- 《Cracking the Coding Interview》——第18章:难题——题目12
- 《Cracking the Coding Interview》——第18章:难题——题目13
- 《Cracking the Coding Interview》——第18章:难题——题目1
- 《Cracking the Coding Interview》——第18章:难题——题目2
- 《Cracking the Coding Interview》——第18章:难题——题目3
- 《Cracking the Coding Interview》——第18章:难题——题目4
- 《Cracking the Coding Interview》——第18章:难题——题目5
- 《Cracking the Coding Interview》——第18章:难题——题目7
- 《Cracking the Coding Interview》——第18章:难题——题目8
- 《Cracking the Coding Interview》——第18章:难题——题目9
- 《Cracking the Coding Interview》——第2章:链表——题目4
- 《Cracking the Coding Interview》——第4章:树和图——题目6
- 《Cracking the Coding Interview》——第7章:数学和概率论——题目4
- 《Cracking the Coding Interview》——第9章:递归和动态规划——题目11
- 《Cracking the Coding Interview》——第11章:排序和搜索——题目8
- 《Cracking the Coding Interview》——第8章:面向对象设计——题目6
- 《Cracking the Coding Interview》——第12章:测试——题目1
- 《Cracking the Coding Interview》——第13章:C和C++——题目1