(剑指Offer)面试题30:最小的k个数
题目:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路:
1、排序
把输入的n个整数排序,然后取前k个数;
时间复杂度:O(nlogn)
2、Partition
通过partition找到第k大的数,它的左边就是前k小的数;
时间复杂度:O(n)
3、最大堆
构建k个整数的最大堆数据结构,然后将剩余n-k个整数依次与堆顶比较,大则抛弃,小则删除堆顶并插入,最后的最大堆就是最小的k个整数;
堆是基于二叉树来实现的,因此插入和删除操作都在O(logk)时间内完成。在代码中可以通过STL中的容器来实现,如set,multiset,priority_queue等,都是基于红黑树实现的,所以是排序的。
时间复杂度:O(nlogk)
代码:
1、Partition方法
#include <iostream>
using namespace std;
int Partition(int* numbers,int start,int end){
int key=numbers[start];
int i=start;
int j=end;
while(i<j){
while(i<j && numbers[j]>=key)
--j;
if(i<j) numbers[i++]=numbers[j];
while(i<j && numbers[i]<=key)
++i;
if(i<j) numbers[j--]=numbers[i];
}
numbers[i]=key;
return i;
}
void GetLeastNumbers(int* input,int n,int* output,int k){
if(input==NULL || output==NULL || k>n || n<=0 || k<=0)
return;
int start=0;
int end=n-1;
int index=Partition(input,start,end);
while(index!=k-1){
if(index>k-1){
end=index-1;
index=Partition(input,start,end);
}
else{
start=index+1;
index=Partition(input,start,end);
}
}
for(int i=0;i<k;i++)
output[i]=input[i];
}
int main()
{
int A[]={4,5,1,6,2,7,3,8};
int len=sizeof(A)/sizeof(A[0]);
int k=4;
GetLeastNumbers(A,len,A,k);
for(int i=0;i<k;i++)
cout<<A[i]<<" ";
cout<<endl;
return 0;
}
2、最大堆/大顶堆
#include <iostream>
#include <set>
#include <vector> using namespace std; typedef multiset<int,greater<int> > inSet;
typedef multiset<int,greater<int> >::iterator setIterator; void GetLeastNumbers_1(const vector<int> &data,inSet &leastNumbers,unsigned int k){
leastNumbers.clear(); if(k<1 || data.size()<k)
return; vector<int>::const_iterator it=data.begin();
for(;it!=data.end();it++){
if(leastNumbers.size()<k)
leastNumbers.insert(*it);
else{
setIterator iterGreatest=leastNumbers.begin();
if(*it<*iterGreatest){
leastNumbers.erase(iterGreatest);
leastNumbers.insert(*it);
}
}
}
} int main()
{
int A[]={4,5,1,6,2,7,3,8};
int len=sizeof(A)/sizeof(A[0]);
int k=4;
vector<int> data(A,A+len); inSet leastNumbers;
GetLeastNumbers_1(data,leastNumbers,k); for(setIterator it=leastNumbers.begin();it!=leastNumbers.end();it++)
cout<<*it<<" ";
cout<<endl; return 0;
}
在线测试OJ:
http://www.nowcoder.com/books/coding-interviews/6a296eb82cf844ca8539b57c23e6e9bf?rp=2
AC代码:
1、Partition方法:
class Solution {
public:
int Partition(vector<int> &data,int start,int end){
int key=data[start];
int i=start;
int j=end;
while(i<j){
while(i<j && data[j]>=key)
j--;
if(i<j)
data[i++]=data[j];
while(i<j && data[i]<=key)
i++;
if(i<j)
data[j--]=data[i];
}
data[i]=key;
return i;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> output;
if(k<1 || input.size()<k)
return output;
int start=0;
int end=input.size()-1;
int index=Partition(input,start,end);
while(index!=k-1){
if(index>k-1){
end=index-1;
index=Partition(input,start,end);
}
else{
start=index+1;
index=Partition(input,start,end);
}
}
for(int i=0;i<k;i++)
output.push_back(input[i]);
return output;
}
};
2、大顶堆:multiset
class Solution {
public:
typedef multiset<int,greater<int> > inSet;
typedef multiset<int,greater<int> >::iterator inSetIterator;
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> output;
if(k<1 || input.size()<k)
return output;
inSet LeastNumbers;
for(vector<int>::iterator it=input.begin();it!=input.end();it++){
if(LeastNumbers.size()<k)
LeastNumbers.insert(*it);
else{
inSetIterator greatest=LeastNumbers.begin();
if(*it<*greatest){
LeastNumbers.erase(*greatest);
LeastNumbers.insert(*it);
}
}
}
for(inSetIterator it=LeastNumbers.begin();it!=LeastNumbers.end();it++)
output.push_back(*it);
return output;
}
};
3、大顶堆:priority_queue
class Solution {
public:
typedef priority_queue<int,vector<int>,less<int> > PQ;
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> output;
if(k<1 || input.size()<k)
return output;
PQ LeastNumbers;
for(vector<int>::iterator it=input.begin();it!=input.end();it++){
if(LeastNumbers.size()<k)
LeastNumbers.push(*it);
else{
int greatest=LeastNumbers.top();
if(*it<greatest){
LeastNumbers.pop();
LeastNumbers.push(*it);
}
}
}
while(!LeastNumbers.empty()){
output.push_back(LeastNumbers.top());
LeastNumbers.pop();
}
return output;
}
};
(剑指Offer)面试题30:最小的k个数的更多相关文章
- 剑指Offer:面试题30——最小的k个数(java实现)
问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...
- 剑指offer 面试题40. 最小的k个数
O(N)划分法,注意这个方法会改变原数据(函数参数是引用的情况下)!当然也可以再定义一个新容器对其划分 要求前k小的数,只要执行快排划分,每次划分都会把数据分成大小两拨.直到某一次划分的中心点正好在k ...
- 剑指Offer - 九度1371 - 最小的K个数
剑指Offer - 九度1371 - 最小的K个数2013-11-23 15:45 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是 ...
- 剑指offer(29)最小的K个数
题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 题目分析 这题有两种方法来做. 第一种就是基于partition的 ...
- 【剑指Offer】29、最小的K个数
题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 解题思路: 本题最直观的解法就是将输入的n个整数排 ...
- 剑指offer面试题30:最小的k个数
一.题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 二.解题思路 1.思路1 首先对数组进行排序,然后取出前k个数 ...
- 面试题30.最小的k个数
题目:输入n个整数,找出其中最小的k个数,例如输入4,5,1,6,2,7,3,8 这8个数字,则最小的四个数字为1,2,3,4, 这道题是典型的TopK问题,剑指Offer提供了两种方法来实现,一种方 ...
- 剑指offer——面试题30:包含min函数的栈
#include"iostream" #include"stdio.h" using namespace std; ; ; template<typena ...
- 剑指offer面试题30.包含min函数的栈
一开始写的垃圾代码,push和pop都是O(N) class Solution { public: vector<int> vec; int min_val=INT_MAX,min_cnt ...
- 【剑指Offer面试题】 九度OJ1371:最小的K个数
题目链接地址: http://ac.jobdu.com/problem.php?pid=1371 题目1371:最小的K个数 时间限制:1 秒内存限制:32 兆特殊判题:否提交:5938解决:1265 ...
随机推荐
- spring.net IOC容器
spring.net 通过配置文件的方式 帮我们实现了IoC功能,实现方式非常灵活,且多种多样. 点击查看 创建对象 我们只需定义接口和实现方法,spring.net帮我们实现了其他功能. 第一步,定 ...
- Windows 小技巧: 變更輸入法順序
Windows XP 中還是有辦法變更輸入法順序的!!只不過,要動用到 Regedit.exe 這個程式. 執行 Regedit.exe至 HKEY_CURRENT_USER\Keyboard Lay ...
- Android 自定义view中的属性,命名空间,以及tools标签
昨日看到有人在知乎上问这3个琐碎的小知识点,今天索性就整理了一下,其实这些知识点并不难,但是很多开发者平时很少注意到这些, 导致的后果就是开发的时候 经常会被ide报错,开发效率很低,或者看开源代码的 ...
- CentOS 6.0 缺少 mcrypt 扩展 解决办法
解决办法:安装php-mcrypt libmcrypt libmcrypt-devel这三个库文件 1.安装第三方yum源(默认yum源里面没有这几个库文件,不能使用yum安装) #wget http ...
- 细雨学习笔记:JMeter 的主要测试组件总结
1. 测试计划是使用 JMeter 进行测试的起点,它是其它 JMeter 测试元件的容器. 2. 线程组代表一定数量的并发用户,它可以用来模拟并发用户发送请求.实际的请求内容在Sampler中定义, ...
- jQuery 关于ScrollableGridPlugin.js(固定表头)插件的逐步解析
以前写前台的时候需要用哪些效果从来都是有现成的东西拿来就用的,因为自己真的是有些懒,毫无探索精神,只重视结果,不追求过程. 这个ScrollableGridPlugin.js是从网上找到的一个具有固定 ...
- 二叉树的基本操作(C)
实现二叉树的创建(先序).递归及非递归的先.中.后序遍历 请按先序遍历输入二叉树元素(每个结点一个字符,空结点为'='): ABD==E==CF==G== 先序递归遍历: A B D E C F G ...
- leetcode:Palindrome Number
Question: Determine whether an integer is a palindrome. Do this without extra space. Some hints: Cou ...
- DOM笔记(五):JavaScript的常见事件和Ajax小结
一.常见事件类型 1.鼠标事件 事件名称 说明 onclick 鼠标单击时触发 ondbclick 鼠标双击时触发 onmousedown 鼠标左键按下时触发 onmouseup 鼠标释放时触发 on ...
- 写在阿里去IOE一周年
[文/ 任英杰] 去年5月17日,阿里巴巴支付宝最后一台IBM小型机在下线,标志着阿里完成去IOE.随后一场去IOE运动不断发酵,甚至传闻IBM中国去年损失了20%的合同额. 去了IOE,奔向何方?阿 ...