您的位置:首页 > 职场人生

剑指offer——面试题30:最小的k个数

2015-08-27 17:27 495 查看
题目描述:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

输入:
每个测试案例包括2行:

第一行为2个整数n,k(1<=n,k<=200000),表示数组的长度。

第二行包含n个整数,表示这n个数,数组中的数的范围是[0,1000 000 000]。

输出:
对应每个测试案例,输出最小的k个数,并按从小到大顺序打印。

样例输入:
8 4
4 5 1 6 2 7 3 8

样例输出:
1 2 3 4

思路1我们通过快排找到第k个数,然后比他的小的都在左边,比他大的都在右边

这个是O(n)的算法,只不过这样做的话会修改输入的数组

#include<iostream>
using namespace std;

void change(int numbers[],int i,int j)
{
int temp=numbers[i];
numbers[i]=numbers[j];
numbers[j]=temp;
}

int partion(int numbers[],int start,int end)
{
if(start==end)
return start;
int temp=numbers[end];
int i=start;
int j=end;
while(i<j)
{
while(i<j&&numbers[i]<=temp)
i++;
change(numbers,i,j);
while(i<j&&numbers[j]>=temp)
j--;
change(numbers,i,j);
}
return  i;
}

int numer_k(int numbers[],int len,int k)
{
if(numbers==NULL||k<=0||k>=len)
return 0;

int start=0;
int end=len-1;
int index=partion(numbers,start,end);

cout<<"index="<<index<<endl;
for(int i=0;i<len;i++)
cout<<numbers[i]<<' ';
cout<<endl;

while(index!=k-1)
{
if(index<k-1)
{
start=index+1;
end=end;
index=partion(numbers,start,end);

cout<<"index="<<index<<endl;
for(int i=0;i<len;i++)
cout<<numbers[i]<<' ';
cout<<endl;

}
else
{
end=index-1;
start=start;
index=partion(numbers,start,end);

cout<<"index="<<index<<endl;
for(int i=0;i<len;i++)
cout<<numbers[i]<<' ';
cout<<endl;
}
}
return numbers[index];
}

int main()
{
int ary[8]={4,5,1,6,2,7,3,8};
cout<<numer_k(ary,8,4)<<endl;

system("pause");
}


思路2:

可以用一个容器存储前面k个数,然后后面的数与这个容器中的最大数作比较,然后若是比这个数大或者相等就不管,接着往后遍历

若是比这个数小就替换掉这个数。

算法复杂度:

这里可以采用最大堆,或者红黑树来存储这个k个数,这样查找最大值时就是O(1)的时间复杂度,但查找和删除时需要O(logk),

而遍历n所以时间复杂度为O(nlogk)。

#include<iostream>
#include<set>
#include<vector>
using namespace std;

int number_k(vector<int>& vec,int k)
{
if(vec.empty())
return 0;
int len=vec.size();
if(len<k||k<=0)
return 0;

multiset<int,greater<int> > mu;
vector<int>::const_iterator i=vec.cbegin();
for(int j=0;j<k;j++)
{mu.insert(*i);i++;}

while(i!=vec.end())
{
int a=*i;
int b=*mu.begin();
if(a<b)
{
mu.erase(b);
mu.insert(a);
}
i++;
}
return *mu.begin();
}
int main()
{

int ary[8]={4,5,1,6,2,7,3,8};
vector<int> vec(ary,ary+8);

cout<<number_k(vec,4)<<endl;
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: