用堆排序实现线性时间查找前K大数字
2014-12-03 09:30
148 查看
1004. 寻找前k大的数(选做) | ||||
| ||||
Time Limit: 1sec Memory Limit:256MB Description <b>选做</b><br> 你的任务是写一个程序来找出N个整数里面前K大的整数,输出按照降序排列。 你可以通过百度了解如何快速找出这K个整数,可以找到时间复杂度为O(N*lgK)的方法。 如果你实在搜不到,ftp上面有个txt文件大概讲了三种方法的思路,可以去看看。 如果面试问到了这个题,优先使用第一种思路,当然如果面试官允许你把三种思路都讲完的话,那也是不错的(前提是你不要自己打脸…要理解它们的复杂度为什么是那样)。 Input 输入有多个测试用例,每个测试用例是两行: 第1行是两个整数N和K,中间用空格隔开(N ≥ K) 第2行有N个整数,每两个数字中间用空格隔开 输入以EOF结束 Output 对于每一个测试用例,输出一行,K个整数,就是它的前K大的整数,按照降序排列输出,每两个数字之间用空格隔开,最后一个数字后面没有空格,有换行。 Sample Input Copy sample input to clipboard 5 23 2 4 1 5 Sample Output 5 4 |
/*包括去重复和不去重复两种,主要是建立最小堆 */ #include <iostream> #include <cstdio> #include <memory.h> using namespace std; //调整堆 void HeapAdjust(int *a, int ¤t, int low, int high) { int large; large = 2 * low + 1; //左儿子 while (large <= high) { if (large < high && a[large] > a[large+1]) large++; if (current <= a[large]) break; else { //继续调整堆 a[low] = a[large]; low = large; large = 2 * low + 1; } } a[low] = current; } void build_heap(int *a, int size) { int current; //建堆,从(size - 2)/2开始 到0 for (int low = (size - 2)/2; low >= 0; low--) { //记录当前值 current = a[low]; HeapAdjust(a, current, low, size - 1); } } void HeapSort(int *a, int size) { int current; //建立堆 build_heap(a, size); for (int i = size - 1; i > 0; i--) { current = a[i]; a[i] = a[0]; HeapAdjust(a, current, 0, i - 1); } } int main() { /* 去重复 //int a[1000]; int k; int n; int size; int find[10000]; int in_it[1000] = {0}; int index = 0; //cout << "请输入要找的规模: "; while (scanf("%d", &n) != EOF) { //memset(in_it, 0, 100000*sizeof(int)); //cout << "请输入要找第几大的数字: "; cin >> k; size = k; int *a = new int[k]; //cout << "输入找的序列: " << endl; for (int i = 0; i < n; i++) cin >> find[i]; //将不重复的数字放进堆中 bool ok = false; int j = 0; for (int i = 0; i < n && ok == false; i++) { bool init = false; for (int m = 0; m < index; m++) { if (in_it[m] == find[i]) init = true; } if (!init) { a[j] = find[i]; j++; in_it[index] = find[i]; index++; if (j == k) ok = true; } } //建堆 build_heap(a, size); //开始寻找 for (int i = 0; i < n; i++) { bool init = false; for (int j = 0; j < index; j++) { if (in_it[j] == find[i]) init = true; } if (init) continue; else { if (find[i] > a[0]) { a[0] = find[i]; build_heap(a, size); } } } HeapSort(a, size); //cout << "前K大数字为:" << endl; cout << a[0]; for (int i = 1; i < k; i++) cout << " " << a[i]; cout << endl; delete []a; } */ //system("pause"); //不去重复 int k; int n; int size = 0; int num; //cout << "请输入要找的规模: "; while (scanf("%d", &n) != EOF) { //memset(in_it, 0, 100000*sizeof(int)); //cout << "请输入要找第几大的数字: "; cin >> k; size = 0; int *a = new int[k]; //cout << "输入找的序列: " << endl; for (int i = 0; i < n; i++) { cin >> num; if (size < k) { a[size] = num; size++; continue; } if (i == k) build_heap(a, size); if (num > a[0]) { a[0] = num; //build_heap(a, size); HeapAdjust(a, num, 0, k - 1); } } HeapSort(a, size); //cout << "前K大数字为:" << endl; cout << a[0]; for (int i = 1; i < k; i++) cout << " " << a[i]; cout << endl; delete []a; } return 0; }
相关文章推荐
- c语言实现线性表的建立,初始化,插入,删除,查找,遍历以及时间复杂度分析
- 线性查找算法的C语言实现
- 一个线性时间复杂度的质因数分解函数(查找全部的素数、得到全部的质因数分解个数)
- 输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字 时间复杂度O(NlogN)
- 【算法学习】线性时间排序-计数排序、基数排序和桶排序详解与编程实现
- 【算法学习】线性时间排序-计数排序、基数排序和桶排序详解与编程实现
- 我写的:用游标实现:查找重复数据并将重复数据加自动增长数字
- 用堆排序实现查找最小的K个元素
- 线性时间查找
- 线性时间查找固定频率的元素
- 三种线性时间O(n)排序算法 - 计数-基数-桶 - C++实现
- GridView控件实现自定义数字、时间、货币字符串格式
- 题目:输入一个已经按升序排序过的数组和一个数字, 在数组中查找两个数,使得它们的和正好是输入的那个数字。 要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。 例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,
- poj 1177 又是一道十分恶心到线段树。 主要是用线段树到区间操作。可以用来节省线性查找的时间。 离散化也十分好的一道题。
- 在有序数组中查找两个数,使得它们的和正好是输入的那个数字。时间复杂度O(n)
- 线性时间内查找第K小(大)算法
- java实现常用的查找(线性查找,折半查找)
- 【练习】输入一个已经按升序排序过的数组和一个数字sum,在数组中查找两个数,使得它们 的和正好是输入的那个数字sum,要求时间复杂度为O(n)
- 输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。 时间复杂度O(N) 空间复杂度O(N)
- 线性时间查找第k大元素