如何求数组中最小的K个值?

icecools 2006-09-28 11:11:53
比如如下数组
array = { 4, 13, 2, 17, 9, 11, 6 }
k = 3
Result = { 2, 4, 6 }
前提是不能改变原数组的内容,另外最好不要申请额外空间来排序后输出,大家有啥好算法?
...全文
260 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
icecools 2006-09-29
  • 打赏
  • 举报
回复
我的意思是不要额外一个数组那么大的空间,一般几个变量还是可以的
另外一个一个找如何实现呢,注意数组里可能有相同的元素
比如
array = { 4, 13, 2, 17, 2, 11, 2 }
icecools 2006-09-29
  • 打赏
  • 举报
回复
楼上的方法不错,而且里面还有优化的可能(每次比较后记录下K中最大的,如果数组下个元素大于这个就直接跳过了)
过会给分!
weijiangshanwww 2006-09-29
  • 打赏
  • 举报
回复
逐个覆盖后,结果肯定是K个最小的留在了你所要输出的数组中,而且没有改变原数组。
weijiangshanwww 2006-09-29
  • 打赏
  • 举报
回复
按照你给的东西,你要找前K个最小的数,而你只给出了K个空间用于放求出的结果。

所以:用插入的话你就可以先默认K个放如这数组中,来个数据比较一下,如果是更小的,则把更大的那个覆盖掉。走一遍就可以比较完毕。
icecools 2006-09-29
  • 打赏
  • 举报
回复
to williamwhy
怎么插入阿?因为不能改变以前数组,所以就会不知道里面的数到底有没有被插入过
weijiangshanwww 2006-09-29
  • 打赏
  • 举报
回复
个人想法:
1:用快速排序的“走步”,每次走步能确定一个元素的位置,如果位置为你要的位置就退出。很多算法书上有的,你可以查查具体算法。

2:用的是堆排序
如果k是小于整个元素个数的1/2,则用k次调整就可以得到第k大的元素...
如果k是大于整个元素个数的1/2,则反着用n-k的来得到第k大的元素...(这样次数少点...)

3:我这里以查找第k小的数为例子,使用快速排序的变种,平均时间复杂度O(n)
如果查找第K个大的数方法类似:
int find(int a[], int n, int k){
int v=a[0];
int b[n-1];
int i,s=0,t=n-2;
for(i=1;i<n;i++){
if(a[i]<v){
b[s++]=a[i];
}else{
b[t--]=a[i];
}
}
if(s==k-1)return v;
if(s<k-1){
return find(b+s,n-s-1,k-s-1);
}else{
return find(b,s,k);
}
}
第二步就很简单了,
int x=find(a,n,k);
for(s=0,i=0;i<n;i++){
if(a[i]<=x&&s<i){
int v=a[i];
a[i]=a[s];
a[s++]=v;
}
}

williamwhy 2006-09-29
  • 打赏
  • 举报
回复
申请K个空间,对数组做插入排序,不知道可以满足要求不
majcos 2006-09-29
  • 打赏
  • 举报
回复
不过要O(k)空间复杂度
majcos 2006-09-29
  • 打赏
  • 举报
回复
使用最小堆如何
icecools 2006-09-29
  • 打赏
  • 举报
回复
顶一下。。。
ysc918 2006-09-29
  • 打赏
  • 举报
回复

楼上的方法不错,而且里面还有优化的可能(每次比较后记录下K中最大的,如果数组下个元素大于这个就直接跳过了)

-----------------------
能解释下吗?具体在程序的什么地方怎么改
fflush 2006-09-28
  • 打赏
  • 举报
回复
不改变原数组,不申请额外空间,那你是把优化的手段都给否定掉了,这样恐怕只能一个一个的找了,时间上为O(kn)

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧