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. hibernate--OneToOne

    一对一(one to one) 单向关联映射 两个对象是一对一的的关系. 有两种策略可以实现一对一的关联映射 l  主键关联:即让两个对象具有相同的主键值,以表明他们之间的一对一的对应关系;数据库表不 ...

  2. 【CentOS】安装jdk

    问题描述:       jdk安装与配置   (1)查看是否安装jdk --CentOS默认自带openjdk         先查看 rpm -qa | grep java         显示如下 ...

  3. mysql 重置root 账户密码

    windows: 打开命令行窗口,停止mysql服务:        Net stop mysql启动mysql,一般到mysql的安装路径,找到 mysqld-nt.exe <<< ...

  4. Python大数据依赖包安装

    一.安装 先安装python2.7.6,win下的numpy这些包需要直接匹配版本,然后安装“numpy-1.8.1-win32-superpack-python2.7”和“scipy-0.16.0- ...

  5. iOS开发如何实现消息推送机制

    一.关于推送通知 推送通知,也被叫做远程通知,是在iOS 3.0以后被引入的功能.是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径,是从外部服务器发送到应用程序上的.一般说来,当要显示消息 ...

  6. (转)Linux进程间通信

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 谢谢nonoob纠错 我们在Linux信号基础中已经说明,信号可以看作一种粗糙的进 ...

  7. POJ 2004 Mix and Build (预处理+dfs)

    题意: 给N个字符串,要求出一个序列,在该序列中,后一个串,是由前一个串加一个字母后得来的(顺序可以改动). 问最多能组成多长的序列.思路:将给的字符串排序,再对所有的字符串按长度从小到大排序,若长度 ...

  8. Bit-Map

    昨日读July大神<教你如何迅速秒杀掉:99%的海量数据处理面试题>博客,有这么一题与大家分享: 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断 ...

  9. CAS登录后回传除了ticket参数以外的其他自定义参数

    在一次项目的技术选型中,选择了easyui+cas+shiro+spring的组合,cas实现了单点登录,这使得在一个应用中嵌入另一个应用的页面来展示数据所涉及到的授权方面变得简单. 由于shiro在 ...

  10. javascript 图片延迟加载

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...