1. 能想到的最直接的办法,就是对数组进行排序,最好的排序算法的时间复杂性为O(n*logn),这一个方法请参照各种排序算法。

2. 另外申请一个k空间数组,依次更改里面的最大值,每做一次最多要扫描一下这个K大小的空间(如果比上一次的最大值大的话,就不用扫描了,所以这里说是“最多”),整体时间复杂度为O((n-k)*k),实现代码如下:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std; int initData(int test[],int len);
int printArray(int test[],int len);
int maxOfArray(int test[],int k);
int selectElement(int test[],int len,int k); int main()
{
const int arraySize=;
const int k=;
int test[arraySize];
initData(test,arraySize);
printArray(test,arraySize);
selectElement(test,arraySize,k);
printArray(test,k);
return ;
}
int selectElement(int test[],int len,int k)
{
int maxIndex=maxOfArray(test,k);
for(int i=k;i<len;i++)
{
int tmp=test[maxIndex];
if(tmp>test[i])
{
test[maxIndex]=test[i];
maxIndex=maxOfArray(test,k);
}
}
return ;
}
int maxOfArray(int test[],int k)
{
int index=;
int tmp=test[];
for(int i=;i<k;i++)
{
if(test[i]>tmp)
{
index=i;
tmp=test[i];
}
}
return index;
}
int initData(int test[],int len)
{
srand(time(NULL));
for(int i=;i<len;i++)
{
test[i]=rand()%;
}
return ; }
int printArray(int test[],int len)
{
for(int i=;i<len;i++)
{
cout<<test[i]<<"\t";
}
cout<<endl;
return ;
}

3.第三种方式是建立一个k大小的极大堆,每一次将数据与堆头的元素比较,如果比它小,则替换之,然后更新堆的结构,除去构建堆的时间,时间复杂度为:O((n-k)*logk),代码如下:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std; int initData(int test[],int len);
int printArray(int test[],int len);
int maxHeap(int test[],int i,int k);//i为下标
int buildHeap(int test[],int arraySize,int k);
int selectElement(int test[],int arraySize,int k);
int main()
{
const int arraySize=;
const int k=;
int test[arraySize];
initData(test,arraySize);
printArray(test,arraySize);
buildHeap(test,arraySize,k);
printArray(test,arraySize);
selectElement(test,arraySize,k);
printArray(test,arraySize);
return ;
}
int selectElement(int test[],int arraySize,int k)
{
for(int i=k;i<arraySize;i++)
{
if(test[i]<test[])
{
test[]=test[i];
maxHeap(test,,k);
}
}
return ;
}
int buildHeap(int test[],int arraySize,int k)
{
for(int i=arraySize/-;i>=;i--)
{
maxHeap(test,i,k);
}
return ;
}
int maxHeap(int test[],int i,int k)//i为下标
{
int least=i;
int left=(i+)*-;
int right=(i+)*;
if(left<k&&test[left]>test[least])
least=left;
if(right<k&&test[right]>test[least])
least=right;
if(least!=i)
{
test[i]=test[i]+test[least];
test[least]=test[i]-test[least];
test[i]=test[i]-test[least];
maxHeap(test,least,k);
}
return ;
}
int initData(int test[],int len)
{
srand(time(NULL));
for(int i=;i<len;i++)
{
test[i]=rand()%;
}
return ; }
int printArray(int test[],int len)
{
for(int i=;i<len;i++)
{
cout<<test[i]<<"\t";
}
cout<<endl;
return ;
}

对堆不了解的这里插入一个3D动画http://www.benfrederickson.com/2013/10/10/heap-visualization.html

4. 第四种方法是借鉴快速排序的partition过程,partition做完后,假设返回的下标是k,那么我们确定k之前的元素都比k下标的元素要小,依次不断递归下去,时间复杂度是O(n),实现代码如下:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int partition(int test[],int p,int r);
int selectElements(int test[],int p,int r,int k);//前k个最小元素;
int initData(int test[],int len);
int printArray(int test[],int len); int main()
{
const int arraySize=;
const int k=;
int test[arraySize];
initData(test,arraySize); printArray(test,arraySize);
selectElements(test,,arraySize-,k);
printArray(test,arraySize);
return ;
}
int selectElements(int test[],int p,int r,int k)//前k个最小元素
{
if(p<=r)
{
int partIndex=partition(test,p,r);
int len=partIndex-p+;
if(len==k)
return ;
else if(len<k)
{
selectElements(test,partIndex+,r,k-len);
}
else
{
selectElements(test,p,partIndex-,k);
}
}
return ;
}
int partition(int test[],int p,int r)
{
int flagValue=test[r];
int k=p-;
for(int i=p;i<r;i++)
{
if(test[i]<flagValue)
{
k++;
/*
test[i]=test[k]+test[i];test[k]与test[i]是同一块区域的话,这样会把数据清0
test[k]=test[i]-test[k];
test[i]=test[i]-test[k];
*/
int tmp=test[k];
test[k]=test[i];
test[i]=tmp;
}
}
k++;
test[r]=test[k];
test[k]=flagValue;
return k; }
int initData(int test[],int len)
{
srand(time(NULL));
for(int i=;i<len;i++)
{
test[i]=rand()%;
}
return ; }
int printArray(int test[],int len)
{
for(int i=;i<len;i++)
{
cout<<test[i]<<"\t";
}
cout<<endl;
return ;
}

寻找最小的k个数的更多相关文章

  1. 算法练习:寻找最小的k个数

    参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650 寻找最小的k个数题目描述:查找最小的k个元素题目:输入n个整数,输出其中 ...

  2. 03寻找最小的k个数

    题目描述:查找最小的k个元素         题目:输入n个整数,输出其中最小的k个.         例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 1:最简单 ...

  3. 算法笔记_035:寻找最小的k个数(Java)

    目录 1 问题描述 2 解决方案 2.1 全部排序法 2.2 部分排序法 2.3 用堆代替数组法 2.4线性选择算法   1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 ...

  4. Java实现寻找最小的k个数

    1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 解决方案 2.1 全部排序法 先对这n个整数进行快速排序,在依次输出前k个数. package com.liuzhen. ...

  5. 寻找最小的k个数(四种方法)

    1 使用从大到小的优先队列保存最小的K个数,每次取出K个数之后的其余数和堆顶元素比较,如果比堆顶元素小,则将堆顶元素删除,将该元素插入 void topK(int arr[],int n,int k) ...

  6. 编程之法:面试和算法心得(寻找最小的k个数)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 输入n个整数,输出其中最小的k个. 分析与解法 解法一 要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个 ...

  7. 算法练习-寻找最小的k个数

    练习问题来源 https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/02.01.html 要求 输入n个整数, ...

  8. 每日一题 - 剑指 Offer 40. 最小的k个数

    题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 快排 难易程度:中等 题目描述: 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3. ...

  9. 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆

    原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...

随机推荐

  1. modernizr.js

    1.判断浏览器是否支持 h5 if(Modernizr.canvas){ alert(123); }else{ alert(321); } 2.判断浏览器是否支持 canvas function su ...

  2. CSS3弹性盒模型,Flex布局教程

    布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. CSS3中引入flex的弹性盒模型 ...

  3. jquery中如何退出each循环

    在for循环中我们用continue退出当前循环,进入下一循环.用break跳出所有循环. 可是在jQuery中却并没有这两条命令,那么如何退出each循环呢? 经过查询得知: 在jQuery中用 r ...

  4. 使用CSS3实现超炫的Loading(加载)动画效果

    SpinKit 是一套网页动画效果,包含8种基于 CSS3 实现的很炫的加载动画.借助 CSS3 Animation 的强大功能来创建平滑,易于定制的动画.SpinKit 的目标不是提供一个每个浏览器 ...

  5. Android fill_parent、wrap_content和match_parent的区别

    三个属性都用来适应视图的水平或垂直大小,一个以视图的内容或尺寸为基础的布局比精确地指定视图范围更加方便. 1)fill_parent 设置一个构件的布局为fill_parent将强制性地使构件扩展,以 ...

  6. Spring mvc json null

    http://blog.csdn.net/zdsdiablo/article/details/9429263

  7. zoj 3057 Beans Game 博弈论

    思路:三维DP,刚开始用记忆化搜索,MLE…… 后来改为直接预处理所有的情况. 总之就是必败态的后继是必胜态!!! 代码如下: #include<iostream> #include< ...

  8. android sdk启动报错error: could not install *smartsocket* listener: cannot bind to 127.0.0.1:5037:

    android sdk启动报错error: could not install *smartsocket* listener: cannot bind to 127.0.0.1:5037: 问题原因: ...

  9. socket传输过程

    连接过程: 根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认. (1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处 ...

  10. 2016CVTE编程题:兔子藏洞

    兔子藏洞 题目描述 一只兔子藏身于20个圆形排列的洞中(洞从1开始编号),一只狼从x号洞开始找,下次隔一个洞找(及在x+2号洞找),在下次个两个洞找(及在x+5号洞找),以此类推...它找了n次仍然没 ...