查找最小的k个元素 【微软面试100题 第五题】
题目要求:
输入n个整数,输出其中最小的k个。
例如:输入1,2,3,4,5,6,7,8这8个数字,则最小的4个数字为1,2,3,4。
参考资料:剑指offer第30题。
题目分析:
解法一:
用快排的思想,但是最小的k个数不用排序,时间复杂度O(n).
优点:时间复杂度好,缺点:会修改原整数数组顺序。
解法二:
创建一个大小为k的最大堆,遍历一遍数组,同时不断修改最大堆。时间复杂度O(nlogk).
优点:不会修改原数组,适用于海量数据。缺点:比解法一时间复杂度高。
其他解法:
1.快排,取前k个数,时间复杂度O(nlogn).
2.遍历k次,时间复杂度O(k*n).
3.位图排序,取前k个数,时间复杂度O(n).会占用额外的空间.
解法一代码:
#include <iostream>
#include <stdlib.h>
using namespace std; inline int my_rand(int low, int high)
{
int size = high - low + ;
return low + rand() % size;
}
int partition(int a[], int low, int high)
{
int val = a[low]; while(low<high)
{
while( (low<high) && (a[high]>=val) )
high--; a[low] = a[high];
while( (low<high) && (a[low] <= val) )
low++;
a[high] = a[low];
}
a[low] = val;
return low;
}
void swap(int *a,int i,int j)
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
bool rand_select(int array[], int left, int right, int k)
{
//第k 小元素,实际上应该在数组中下标为 k-1
if (k- > right || k- < left)
return false ; if(left<right)
{
//随机从数组中选取枢纽元元素
int index = my_rand(left, right);
swap(array,index,left); int pos = partition(array , left, right);
if(pos == k-)
return true ;
else if (pos > k-)
return rand_select(array , left, pos-, k);
else return rand_select(array, pos+, right, k);
}
else
return true ;
}
int main()
{
int array1[] = {, , , , , , , , , }; int numOfArray = sizeof (array1) / sizeof( int);
for(int i=; i<numOfArray; i++)
cout << array1[i] << " ";
cout << endl; int K = ;
bool flag = rand_select(array1, , numOfArray-, K); if(flag)
{
cout << "最小的" << K << "个数为:";
for(int i=; i<K; i++)
cout << array1[i] << " ";
cout << endl;
}
return ;
}
解法二代码:
//从头实现一个最大堆需要一定的代码,可以采用c++中的红黑树来实现。
//其中set和multiset都是基于红黑树实现的,后者可以支持数组中有重复
#include <iostream>
#include <set>
#include <vector> using namespace std; typedef multiset<int,greater<int>> intSet;
typedef multiset<int,greater<int>>::iterator setIterator; void getLeastNumbers(const vector<int> &data,intSet &leastNumbers,int k); int main(void)
{
int a[] = {,,,,,,,};
const vector<int> data(a,a+);//8不是7 intSet leastNumbers;
int k = ; getLeastNumbers(data,leastNumbers,k); cout << "最小的" << k << "个数为:";
setIterator iter = leastNumbers.begin();
for(;iter!=leastNumbers.end();++iter)
cout << *iter << " ";
cout << endl;
return ;
}
void getLeastNumbers(const vector<int> &data,intSet &leastNumbers,int k)
{
leastNumbers.clear(); if(k< || k>data.size())
return ; vector<int>::const_iterator iter = data.begin();
for(;iter != data.end();++iter)
{
if(leastNumbers.size() < k)
leastNumbers.insert(*iter);
else
{
setIterator iterGreatest = leastNumbers.begin();
if(*iter < *iterGreatest)
{
leastNumbers.erase(*iterGreatest);
leastNumbers.insert(*iter);
}
}
}
}
查找最小的k个元素 【微软面试100题 第五题】的更多相关文章
- 查找最小的k 个元素之C#算法实现
紧接着上一篇微软编程面试100题,这次想解决的是查找最小的K个元素,题目是:输入n 个整数,输出其中最小的k 个.例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 ...
- 【编程题目】查找最小的 k 个元素
5.查找最小的 k 个元素(数组)题目:输入 n 个整数,输出其中最小的 k 个.例如输入 1,2,3,4,5,6,7 和 8 这 8 个数字,则最小的 4 个数字为 1,2,3 和 4. 算法里面学 ...
- 查找最小的K个元素,使用最大堆。
查找最小的K个元素,使用最大堆,具体代码如下: #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace st ...
- 【Data Structure & Algorithm】 查找最小的k个元素
查找最小的k个元素 题目:输入n个整数,输出其中最小的k个. 例如输入1, 2, 3, 4, 5, 6, 7和8这八个数字,则最小的4个数字为1, 2, 3和4. 分析:这道题最简单的思路是把输入的n ...
- 程序员面试50题(1)—查找最小的k个元素[算法]
题目:输入n个整数,输出其中最小的k个.例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 分析:这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前面的k个数 ...
- 5.查找最小的k个元素[Kmin]
[题目] 输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. [分析] 这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前 ...
- 5.查找最小的k个元素(数组)
题目: 输入n个整数,输出其中最小的k个,例如输入1,2,3,4,5,6,7,8这8个数,则最小的4个是1,2,3,4(输出不要求有序) 解: 利用快速排序的partition,算导上求第k大数的思想 ...
- 查找最小的k个元素
题目:输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 两种思路,无非就是时间与空间的妥协. 限制空间的时候要对原数组进行排序, ...
- IT公司100题-5-查找最小的k个元素
问题描述: 输入n 个整数,输出其中最小的k 个. 例如输入8, 7, 6, 5, 4, 3, 2, 1这8 个数字,则最小的3 个数字为3, 2, 1. 分析: 时间复杂度O(nlogn)方法: ...
随机推荐
- Guice入门
参考链接:http://www.cnblogs.com/xd502djj/archive/2012/06/25/2561414.html Google Guice范例解说之使用入门 http://co ...
- mongodb关联查询 和spring data mongodb
GITHUB:https://github.com/peterowang/Springdata-mongo 使用DBRefs DBRefs中有三个字段 - $ref - 此字段指定引用文档的集合 $i ...
- .Net平台互操作技术:03. 技术验证
上面两篇文章分别介绍了.Net平台互操作技术面临的问题,并重点介绍了通过P/Invoke调用Native C++类库的技术实现.光说不做是假把式,本文笔者将设计实验来证明P/Invoke调用技术的可行 ...
- Java-Web总结03
*1 dom4j解析器 1)CRUD的含义:CreateReadUpdateDelete增删查改 2)XML解析器有二类,分别是DOM和SAX. a)DOM一次性将整个XML文件读到内存,形成 ...
- 重温Javascript(三)-继承
继承 1.原型链继承 基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.让原型 ...
- 使用JS的画布制作一个瞄准镜
<canvas width="600" height="500" id="myCanvas"></canvas> & ...
- [CV笔记]inRange对图像进行分割
先把图像转为hsv空间,然后对图像进行inrange取到hsv范围内的图像,我这里要做的是取到图中的几个白色区域以及里面的手写数字,方法可能不是最好的,因为刚入门cv没几天,先试着用所学取到这几个区域 ...
- 查询linux文件的MD5值
Linux下查询文件的MD5值:md5sum xxx.iso.md5 MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改.MD5全称是报文摘要算法(Message-Digest Algor ...
- java static block
java 中 静态块的作用 (一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在 ...
- java基础——快速排序
今天又把以前学的快速排序拿出来回忆一下 高快省的排序算法 有没有既不浪费空间又可以快一点的排序算法呢?那就是“快速排序”啦!光听这个名字是不是就觉得很高端呢. 假设我们现在对“6 1 2 7 9 3 ...