寻找最小的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在很多情 ...
随机推荐
- 03.RedisJava客户端Jedis的使用
1.Jedis基本使用 使用Jedis客户端使用Redis服务与在服务器上通过redis-cli使用命令基本一样,关于Redis命令请参考:http://www.redis.cn/commands.h ...
- 01.Hibernate入门
前言:本文用一个简单的Hibernate应用程序例子来引领初学者入门,让初学者对Hibernate的使用有一个大致的认识.本文例子使用了MySQL数据库.Maven管理工具.Eclipse开发工具,创 ...
- 编译libcore-amr静态库
在此链接下 https://github.com/feuvan/opencore-amr-iOS 下载它的源码到本地, 然后cd到此目录下,在终端输入命令./build_ios_xcode6.sh,便 ...
- C语言中inline的用法
C语言里面的内联函数(inline)与宏定义(#define)探讨 先简明扼要,说下关键: 1.内联函数在可读性方面与函数是相同的,而在编译时是将函数直接嵌入调用程序的主体,省去了调用/返回指令,这样 ...
- YTKNetwork
YTKNetwork 是猿题库 iOS 研发团队基于 AFNetworking 封装的 iOS 网络库,其实现了一套 High Level 的 API,提供了更高层次的网络访问抽象. YTKNetwo ...
- 初识layer 快速入门
http://layer.layui.com/hello.html 如果,你初识layer,你对她不知所措,你甚至不知如何绑定事件… 那或许你应该用秒做单位,去认识她. 开始了解 第一步:部署 下载l ...
- PHP 中 Date 函数与实际时间相差8小时的解决方法
PHP 中的 date() 函数显示的时间是格林威治时间,和北京时间正好相差8个小时,其他时间相关的函数,如 strtotime() 也有相同的问题,同样可以通过下面的方法来解决: 1. 修改php. ...
- HDU 2672 god is a girl (字符串处理,找规律,简单)
题目 //1,1,2,3,5,8,13,21,34,55…… //斐波纳契数列 #include<math.h> #include<stdio.h> #include<s ...
- HDU 2126 Buy the souvenirs (01背包,输出方案数)
题意:给出t组数据 每组数据给出n和m,n代表商品个数,m代表你所拥有的钱,然后给出n个商品的价值 问你所能买到的最大件数,和对应的方案数.思路: 如果将物品的价格看做容量,将它的件数1看做价值的话, ...
- awk处理之案例三:awk去掉不需要的文本行
编译环境 本系列文章所提供的算法均在以下环境下编译通过. [脚本编译环境]Federa 8,linux 2.6.35.6-45.fc14.i686 [处理器] Intel(R) Core(TM)2 Q ...