查找最小的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)方法: ...
随机推荐
- Linux下常用的数据恢复工具
一.数据删除 命令:rm -rf,将任何数据直接从硬盘删除,且没有任何提示 建议做法: 把命令参数放到后面:rm -rfi 将删除的东西通过mv命令移动到系统下的/temp目录下,然后写个脚 本定期执 ...
- elasticsearch 2.4 windows版jvm内存设置
本文编写目的是因为网上有很多es修改内存配置的文章,方法也各有不同,但在我的情况下(es 2.4 windows版)发现很多方法都是无效的,有效只有以下方法 第一个是xms,第二个是xmx
- Android用RecyclerView实现的二维Excel效果组件
excelPanel 二维RecyclerView.不仅可以加载历史数据,而且可以加载未来的数据. 包括在您的项目中 excelPanel 二维RecyclerView.不仅可以加载历史数据,而且 ...
- 如何在cmd查看文件内容的md5值
在cmd下进入 要查看的文件目录 默认目录是c,切换到其他盘符例如: C:\D: 就会切换到D盘 D:\ 然后输入命令 certutil -hashfile 文件名称.文件类型 MD5 如 cert ...
- git的常用操作指令
git学习网址: http://www.backlogtool.com/git-guide/cn/intro/intro2_3.html 廖雪峰的git教程 git的工作区和暂存区(描述git的工作流 ...
- openfire4.0.2源码 使用 IntelliJ IDEA 搭建开发环境
从官网下载压缩包,解压,直接打开build目录下的project 打开后, 相关的设置 fix直接修复或者下载 设置 设置每个插件目录下的java目录为source 编译openfire和plugin ...
- 问题驱动的Git学习
(搬运自我在SegmentFault的博客) 本人是个Git新手,平时用Git最多的就是push,因为别的都不怎么会用.这几天因为在小组中负责代码的整合,顺便将代码提交到Github,接触到了Git更 ...
- [CV笔记]inRange对图像进行分割
先把图像转为hsv空间,然后对图像进行inrange取到hsv范围内的图像,我这里要做的是取到图中的几个白色区域以及里面的手写数字,方法可能不是最好的,因为刚入门cv没几天,先试着用所学取到这几个区域 ...
- Typescript的优势
TypeScript是一种由微软开发的自由开源的编程语言,他是JavaScript的一个超集,扩展了JavaScript的语法. 优势: 一.Angular2框架的开发语言 Angular2是一款开源 ...
- tpcc-mysql 实践
一.TPCC 介绍 TPC:全称Transaction Processing Performance Council (事务处理性能委员会),是一家非盈利性组织,该组织制定各种商业应用的基准测试规范, ...