题目:输入n个整数,输出其中最小的k个。

例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。

两种思路,无非就是时间与空间的妥协。

限制空间的时候要对原数组进行排序,最好的时间复杂度是O(nlogn),由此可见,当牺牲一部分空间的时候会换来时间复杂度的降低。进而再想到利用一个大小为K的临时数组,来存储K个最小的值,在遍历原数组的同时,更新临时数组里的数据就OK了。那么,现在的问题就是更新临时数组,怎样才能每访问一个数据,都能使临时数组里的数据是最小的K个。自然想到选出临时数组里面的最大值,和原数组里的新访问的值进行比较,判断是否替换最大值。遍历原数组的时间复杂度是O(n)那么,选择临时数组的最大值的时间复杂度要小于O(logn)才对得住牺牲的空间复杂度。。。

现在,马上想到的选择最大值的方法是进行一趟冒泡,但时间复杂度是O(K)不见得比O(logn)小。能比O(logn)小的,自然就想到了O(logk),见到logk就想到了二叉树或者说是堆。。。嗯,也就是大根堆

当元素个数小于k的时候,直接把原数组里面的数据直接放到临时数组里面,当达到k后,便建立大根堆——选出最大的和原数组的新数据进行比较(每次的时间复杂度为logk,这样共要进行n-k次,因此,时间复杂度是O(nlogk)。但是,还有一种做法,是原地比较,将原数组建成一个小根堆,然后输出k次,就可以在原数组末端得出最小的k个数据,这样的时间复杂度应该是max(O(n)[建堆]+O(klogn)[选出k个]),和利用临时数组的比不知哪个的时间复杂度会更低。

下面是利用临时数组的做法:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. void HeapAdjust(int* a,int length,int i){
  4. int lchild = * i ;
  5. int rchild = * i + ;
  6. int max = i;
  7. if(lchild < length&&a[max] < a[lchild])
  8. max = lchild;
  9. if(rchild < length&&a[max] < a[rchild])
  10. max = rchild;
  11. int temp = a[max];
  12. if(max != i){
  13. a[max] = a[i];
  14. a[i] = a[max];
  15. HeapAdjust(a,length,max);
  16. }
  17. }
  18. void HeapSort(int*temp,int*a,int length,int k){//遍历原数组,更新临时数组
  19. for(int i = k + ; i <= length; i++){
  20. if(temp[] > a[i]){
  21. temp[] = a[i];
  22. HeapAdjust(temp,k,);
  23. }
  24. }
  25. void HeapBuild(int* a,int length){
  26. for(i = length / ; i > ; i--)
  27. HeapAdjust(a,length,i);
  28. }
  29. void minKvalue(int* a,int length,int k){//所要求功能函数
  30. if(k > length||k < ||length < )
  31. return ;
  32. int* temp = (int*)malloc(sizeof(int)*(k + ));
  33. int i;
  34. for(i = ; i <= k; i++)
  35. temp[i] = a[i];
  36. BuildHeap(temp,k);
  37. HeapSort(temp,a,length,k);
  38. for(i = ; i <= k; i++)
  39. printf("%4d",temp[i]);
  40. printf("\n");
  41. free(temp);
  42. }
  43. int main(){//测试函数
  44. int length,*a;
  45. printf("输入数组长度:\n");
  46. scanf("%d",&length);
  47. a = (int*)malloc(sizeof(int)*(length + ));
  48. printf("输入%d个数据:\n");
  49. for(int i = ; i <= length; i++)
  50. scanf("%d",a + i);
  51. minKvalue(a,temp,length,k);
  52. free(a);

查找最小的k个元素的更多相关文章

  1. 【编程题目】查找最小的 k 个元素

    5.查找最小的 k 个元素(数组)题目:输入 n 个整数,输出其中最小的 k 个.例如输入 1,2,3,4,5,6,7 和 8 这 8 个数字,则最小的 4 个数字为 1,2,3 和 4. 算法里面学 ...

  2. 查找最小的k 个元素之C#算法实现

    紧接着上一篇微软编程面试100题,这次想解决的是查找最小的K个元素,题目是:输入n 个整数,输出其中最小的k 个.例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 ...

  3. 查找最小的K个元素,使用最大堆。

    查找最小的K个元素,使用最大堆,具体代码如下: #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace st ...

  4. 【Data Structure & Algorithm】 查找最小的k个元素

    查找最小的k个元素 题目:输入n个整数,输出其中最小的k个. 例如输入1, 2, 3, 4, 5, 6, 7和8这八个数字,则最小的4个数字为1, 2, 3和4. 分析:这道题最简单的思路是把输入的n ...

  5. 5.查找最小的k个元素[Kmin]

    [题目] 输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. [分析] 这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前 ...

  6. 5.查找最小的k个元素(数组)

    题目: 输入n个整数,输出其中最小的k个,例如输入1,2,3,4,5,6,7,8这8个数,则最小的4个是1,2,3,4(输出不要求有序) 解: 利用快速排序的partition,算导上求第k大数的思想 ...

  7. 程序员面试50题(1)—查找最小的k个元素[算法]

    题目:输入n个整数,输出其中最小的k个.例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 分析:这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前面的k个数 ...

  8. 查找最小的k个元素 【微软面试100题 第五题】

    题目要求: 输入n个整数,输出其中最小的k个. 例如:输入1,2,3,4,5,6,7,8这8个数字,则最小的4个数字为1,2,3,4. 参考资料:剑指offer第30题. 题目分析: 解法一: 用快排 ...

  9. IT公司100题-5-查找最小的k个元素

    问题描述: 输入n 个整数,输出其中最小的k 个. 例如输入8, 7, 6, 5, 4, 3, 2, 1这8 个数字,则最小的3 个数字为3, 2, 1.   分析: 时间复杂度O(nlogn)方法: ...

随机推荐

  1. Struts 和Spring的核心控制器

    Struts 核心控制器是FilterDispatch Spring核心控制器是DispatchServlet

  2. Android开发之布局优化

    1.抽象布局标签 (1) <include>标签 include标签经常使用于将布局中的公共部分提取出来供其它layout共用,以实现布局模块化.这在布局编写方便提供了大大的便利. 以下以 ...

  3. 度小于所述过程:es.exe

    在防火墙管理,见未知的过程"es.exe" 程序信息: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGVzdGNzX2Ru/font ...

  4. Android基础之在Eclipes中关联SDK源码和查看SDK源码

    在进行Android应用开发的时候,我们有时候需要查看某个类或接口的源码从而了解如何去使用一个类或者实现一个接口,查看源码有助于我们的学习某个封装的类的底层是如何实现的,这样可以帮助我们掌握类或者接口 ...

  5. zoj 2966 Build The Electric System

    就是套了个prim算法就ac了 #include <stdio.h> #include <string.h> #define MaxInt 0x3f3f3f3f #define ...

  6. error 和 exception 有什么区别?

    1.error指恢复不是不可能但非常困难的情况下的一种严重错误.比如内存溢出,不指望程序可以处理这样的情况. 2.exception表示一种设计或者实现问题,如果程序正常运行,则从不会发生.

  7. BZOJ 1296: [SCOI2009]粉刷匠( dp )

    dp[ i ][ j ] = max( dp[ i - 1 ][ k ] + w[ i ][ j - k ] )  ( 0 <= k <= j ) 表示前 i 行用了 j 次粉刷的机会能正 ...

  8. php平均拆分大文件为N个小文件

    用PHP程序拆分大文件为N个小文件 /* 假设有文件data.log , 内容如下,行数很多,假设有上亿条数据,文件大小大概在800M左右 92735290 80334472 49114074 871 ...

  9. QWidget QMainWindow QDialog 之间的区别

    QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个原子:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己的表现.每一个窗口部件都是矩形,并且它们按Z轴顺序排列的.一个窗口部 ...

  10. RESTClient 控件 从服务器获得数据集 REST

    用TRESTClient控件调用REST架构服务 RESTClient控件返回数据集 用到的控件 RESTClient RESTRequest RESTResponseDataSetAdapter p ...