寻找最小的k个数
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个数的更多相关文章
- 算法练习:寻找最小的k个数
参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650 寻找最小的k个数题目描述:查找最小的k个元素题目:输入n个整数,输出其中 ...
- 03寻找最小的k个数
题目描述:查找最小的k个元素 题目:输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 1:最简单 ...
- 算法笔记_035:寻找最小的k个数(Java)
目录 1 问题描述 2 解决方案 2.1 全部排序法 2.2 部分排序法 2.3 用堆代替数组法 2.4线性选择算法 1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 ...
- Java实现寻找最小的k个数
1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 解决方案 2.1 全部排序法 先对这n个整数进行快速排序,在依次输出前k个数. package com.liuzhen. ...
- 寻找最小的k个数(四种方法)
1 使用从大到小的优先队列保存最小的K个数,每次取出K个数之后的其余数和堆顶元素比较,如果比堆顶元素小,则将堆顶元素删除,将该元素插入 void topK(int arr[],int n,int k) ...
- 编程之法:面试和算法心得(寻找最小的k个数)
内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 输入n个整数,输出其中最小的k个. 分析与解法 解法一 要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个 ...
- 算法练习-寻找最小的k个数
练习问题来源 https://wizardforcel.gitbooks.io/the-art-of-programming-by-july/content/02.01.html 要求 输入n个整数, ...
- 每日一题 - 剑指 Offer 40. 最小的k个数
题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 快排 难易程度:中等 题目描述: 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3. ...
- 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...
随机推荐
- ansii、unicode、utf8 区别和关系
本地化过程中涉及到源文件和目标文件的传输问题,这时候编码就显得很重要.中文的网页和操作系统中通常采用ANSI编码,这也是微软OS的一个字符标准.对于ANSI,不同的国家和地区制定了不同的标准,由此产生 ...
- bzoj 3039 悬线法求最大01子矩阵
首先预处理每个F点左右,下一共有多少个F点,然后 对于每个为0的点(R),从这个点开始,一直到这个点 下面第一个R点,这一区间中的min(左),min(右)更新答案. ps:我估计这道题数据有的格式不 ...
- 二分图匹配(KM算法)n^4 分类: ACM TYPE 2014-10-04 11:36 88人阅读 评论(0) 收藏
#include <iostream> #include<cstring> #include<cstdio> #include<cmath> #incl ...
- LAMP一键安装包-CentOS 5/6下自动编译安装Apache,MySQL,PHP
http://www.centos.bz/lamp/ 此安装包已经不再维护,请使用新版http://www.centos.bz/ezhttp/. 适用环境: 系统支持:CentOS-5 (32bit/ ...
- xp/2003开关3389指令
开启3389: @echo offtitle 开启3389clsrem 开启3389reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ ...
- Base64编解码Android和ios的例子,补充JNI中的例子
1.在Android中java层提供了工具类:android.util.Base64; 里面都是静态方法,方便直接使用: 使用方法如下: // Base64 编码: byte [] encode = ...
- 在centos 6.5 在virtual box 上 安装增强版工具
centos 6.5 在virtual box 上 安装增强版工具: 出现:centos unable to find the source of your current linux kernel ...
- HDOJ 1220 Cube
CubeTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- 时序列数据库武斗大会之 OpenTSDB 篇
[编者按] 刘斌,OneAPM后端研发工程师,拥有10多年编程经验,参与过大型金融.通信以及Android手机操作系的开发,熟悉Linux及后台开发技术.曾参与翻译过<第一本Docker书> ...
- JQuery拾遗
1.关于JQuery的animate,可以操作background么? 答:如果是单纯的JQuery不可以,需要引入JQuery的ui核心库.否则只支持宽高.透明度.上下左右位置的变化. 2.能否说一 ...