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

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

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

        public static void Quick_Sort(int[] sort, int left, int right)
{
int mid = sort[(left + right) / 2];
int i = left;
int j = right;
do
{
while (sort[i] < mid && i < right) i++;
while (sort[j] > mid && j > left) j--;
if (i <= j)
{
int temp = sort[i];
sort[i] = sort[j];
sort[j] = temp;
i++;
j--;
} } while (i <= j); if (j > left) Quick_Sort(sort, left, j);
if (i < right) Quick_Sort(sort, i, right);
}

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

        public static void MinKMethod(int[] sort, int k)
{
Quick_Sort(sort, 0, sort.Length - 1);
if (k > sort.Length)
{
for (int j = 0; j < sort.Length; j++)
{
Console.Write(sort[j] + " ");
}
Console.WriteLine();
}
if (k <= 0)
{
Console.WriteLine("Nothing Output");
}
if (k > 0 && k < sort.Length)
{
for (int j = 0; j < k; j++)
{
Console.Write(sort[j] + " ");
}
} }

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

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

        public static void FindKMin(int[] sort, int k)
{
int[] heap = sort;
int rootIndex = k / 2 - 1;
while (rootIndex >= 0)
{
reheap(heap, rootIndex, k - 1);
rootIndex--;
} for (int i = k, len=heap.Length; i < len; i++)
{
if (heap[i]<heap[0])
{
heap[0] = heap[i];
reheap(heap, 0, k - 1);
}
} Console.WriteLine("The {0} min element =",k);
for (int i = 0; i < k; i++)
{
Console.Write(heap[i] + " ");
}
} private static void reheap(int[] heap, int rootIndex, int lastInddex)
{
int orphan = heap[rootIndex];
bool done = false;
int leftIndex = rootIndex * 2 + 1;
while (!done && leftIndex <= lastInddex)
{
int largerIndex = leftIndex;
if (leftIndex+1 <= lastInddex)
{
int rightIndex = leftIndex + 1;
if (heap[rightIndex] > heap[leftIndex])
{
largerIndex = rightIndex;
}
} if (orphan < heap[largerIndex])
{
heap[rootIndex] = heap[largerIndex];
rootIndex = largerIndex;
leftIndex = rootIndex * 2 + 1;
}
else
{
done = true;
}
} heap[rootIndex] = orphan;
}

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

查找最小的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. 使用MySQL Migration Toolkit快速将Oracle数据导入MySQL[转]

    使用MySQL Migration Toolkit快速将Oracle数据导入MySQL上来先说点废话本人最近在学习一些数据库方面的知识,之前接触过Oracle和MySQL,最近又很流行MongoDB非 ...

  2. [LeetCode] Longest Increasing Subsequence

    Longest Increasing Subsequence Given an unsorted array of integers, find the length of longest incre ...

  3. nodejs express 框架解密3-中间件模块

    本文档是基于express 3.4.6 的 在上篇中我们提到了中间件,这篇主要解释这个模块,middleware.js 为: var utils = require('./utils'); /** * ...

  4. 网页内容导出word/excel的js代码

    IE设置: 工具-> Internet选项-> 安全->自定义级别-> 对没有标记安全级别的ActiveX控件进行初始化  设为启用! 1.导出word //指定区域导出到Wo ...

  5. H5长按事件

    let timeOutEvent = 0 $(function () { $('#debug').on({ touchstart: function (e) { setTimeout(function ...

  6. Linux查看端口、进程情况及kill进程

    看端口: ps -aux | grep tomcat 发现并没有8080端口的Tomcat进程. 使用命令:netstat –apn 查看所有的进程和端口使用情况.发现下面的进程列表,其中最后一栏是P ...

  7. 同步与异步&阻塞与非阻塞

    摘要 一直为同步异步,阻塞非阻塞概念所困扰,特定总结了下,原来是这么个意思 一直为同步异步,阻塞非阻塞概念所困扰,特定总结了下 一.同步与异步的区别 1.概念介绍 同步:所谓同步是一个服务的完成需要依 ...

  8. LoadRunner11.52发布,全新的VTS

    LoadRunner11.52发布,全新的VTShttp://automationqa.com/forum.php?mod=viewthread&tid=2252&fromuid=2 ...

  9. SQL语句 - 基本查询

    select select_list [ into new_table ] from table_source [ where search_condition ] [ group by broup_ ...

  10. 【转】sql里面的split

    CREATE function [dbo].[SplitString]( @Input nvarchar(max), @Separator nvarchar(max)=',', @RemoveEmpt ...