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

看到题目的时候我第一反应,这题很简单,使用任何方式的排序将数列按顺序存储,之后遍历需要的k个元素即可,于是自己动手很容易就完成了,但是后来在网络上发现很多人对这题的解决方式是用小根堆(MinHeap)或者大根堆(MaxHeap),这才意识到,其实出题人是醉翁之意不在酒,在乎复杂度的考虑也。

先写用排序的方式完成题目的方式吧,不仅简单,不需要费太多脑子,重要的是,正好趁这时候复习下排序,这里用快速排序完成:

  1. public static void Quick_Sort(int[] sort, int left, int right)
  2. {
  3. int mid = sort[(left + right) / 2];
  4. int i = left;
  5. int j = right;
  6. do
  7. {
  8. while (sort[i] < mid && i < right) i++;
  9. while (sort[j] > mid && j > left) j--;
  10. if (i <= j)
  11. {
  12. int temp = sort[i];
  13. sort[i] = sort[j];
  14. sort[j] = temp;
  15. i++;
  16. j--;
  17. }
  18.  
  19. } while (i <= j);
  20.  
  21. if (j > left) Quick_Sort(sort, left, j);
  22. if (i < right) Quick_Sort(sort, i, right);
  23. }

然后定义一个MinKMethod的方法来获取所需元素:

  1. public static void MinKMethod(int[] sort, int k)
  2. {
  3. Quick_Sort(sort, 0, sort.Length - 1);
  4. if (k > sort.Length)
  5. {
  6. for (int j = 0; j < sort.Length; j++)
  7. {
  8. Console.Write(sort[j] + " ");
  9. }
  10. Console.WriteLine();
  11. }
  12. if (k <= 0)
  13. {
  14. Console.WriteLine("Nothing Output");
  15. }
  16. if (k > 0 && k < sort.Length)
  17. {
  18. for (int j = 0; j < k; j++)
  19. {
  20. Console.Write(sort[j] + " ");
  21. }
  22. }
  23.  
  24. }

这么做的话,最快需要O(NlogN)的时间进行排序,然后在O(1)的时间内将k个数取出。

接下来看看如何用堆完成这个题:

  1. public static void FindKMin(int[] sort, int k)
  2. {
  3. int[] heap = sort;
  4. int rootIndex = k / 2 - 1;
  5. while (rootIndex >= 0)
  6. {
  7. reheap(heap, rootIndex, k - 1);
  8. rootIndex--;
  9. }
  10.  
  11. for (int i = k, len=heap.Length; i < len; i++)
  12. {
  13. if (heap[i]<heap[0])
  14. {
  15. heap[0] = heap[i];
  16. reheap(heap, 0, k - 1);
  17. }
  18. }
  19.  
  20. Console.WriteLine("The {0} min element =",k);
  21. for (int i = 0; i < k; i++)
  22. {
  23. Console.Write(heap[i] + " ");
  24. }
  25. }
  26.  
  27. private static void reheap(int[] heap, int rootIndex, int lastInddex)
  28. {
  29. int orphan = heap[rootIndex];
  30. bool done = false;
  31. int leftIndex = rootIndex * 2 + 1;
  32. while (!done && leftIndex <= lastInddex)
  33. {
  34. int largerIndex = leftIndex;
  35. if (leftIndex+1 <= lastInddex)
  36. {
  37. int rightIndex = leftIndex + 1;
  38. if (heap[rightIndex] > heap[leftIndex])
  39. {
  40. largerIndex = rightIndex;
  41. }
  42. }
  43.  
  44. if (orphan < heap[largerIndex])
  45. {
  46. heap[rootIndex] = heap[largerIndex];
  47. rootIndex = largerIndex;
  48. leftIndex = rootIndex * 2 + 1;
  49. }
  50. else
  51. {
  52. done = true;
  53. }
  54. }
  55.  
  56. heap[rootIndex] = orphan;
  57. }

用堆解决这个问题其实思路并不难,前提是,需要对堆有一定的理解。

查找最小的k 个元素之C#算法实现的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 查找最小的k个元素

    题目:输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 两种思路,无非就是时间与空间的妥协. 限制空间的时候要对原数组进行排序, ...

  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. Web 开发常备工具

    工欲善其事,必先利其器.如今 Web 开发标准越来越高,Web 开发者也在不断寻找途径提升自己的技能.为使大家的开发工作更顺利进行,本文整理了 10+ 款比较优秀的 Web 开发工具,希望对你有帮助. ...

  2. android:themes.xml

    <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2006 The Andr ...

  3. android实现自动升级并安装打开

    http://blog.csdn.net/wa991830558/article/details/41014673 这是一个比较简单的程序,但网上还是有很多人问起这个问题,并且回答的人,也没有完全回答 ...

  4. JavaScript跨域方法

    一.什么是跨域 JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: ...

  5. C# Like参数化 小记

    strBuilder.Append(" and b.name like '%' + @name + '%'"); parameters.Add(new SqlParameter(& ...

  6. Mesos源码分析

    Mesos源码分析(1): Mesos的启动过程总论 Mesos源码分析(2): Mesos Master的启动之一 Mesos源码分析(3): Mesos Master的启动之二 Mesos源码分析 ...

  7. Vim 练级攻略

    以下的文章翻译自<Learn Vim Progressively>,我认为这是给新手最好的VIM的升级教程了,没有列举全部的命令,仅仅是列举了那些最实用的命令. 很不错. -------- ...

  8. make menuconfig出错解决方法

     make menuconfig出错解决方法 2011-06-11 22:22:49 分类: 系统运维 错误现象: make menuconfig In file included from scri ...

  9. android studio ndk使用openMP

    好久没碰ndk了,之前都是在eclipse下写makefile配置c++程序的,现在发现主流都是用android studio,eclipse俨然已经被遗弃了,正好最近项目需要用openMP做算法加速 ...

  10. javaScript数据类型与typeof操作符

    1,typeof操作符. typeof操作符是用来检测变量的数据类型.使用:typeof  变量名;返回以下字符串: 字符串 描述 undefined 未定义 boolean 布尔值 string 字 ...