题目要求:

  输入n个整数,输出其中最小的k个。

  例如:输入1,2,3,4,5,6,7,8这8个数字,则最小的4个数字为1,2,3,4。

参考资料:剑指offer第30题。

题目分析:

  解法一:

    用快排的思想,但是最小的k个数不用排序,时间复杂度O(n).

    优点:时间复杂度好,缺点:会修改原整数数组顺序。

  解法二:

    创建一个大小为k的最大堆,遍历一遍数组,同时不断修改最大堆。时间复杂度O(nlogk).

    优点:不会修改原数组,适用于海量数据。缺点:比解法一时间复杂度高。

  其他解法:

    1.快排,取前k个数,时间复杂度O(nlogn).

    2.遍历k次,时间复杂度O(k*n).

    3.位图排序,取前k个数,时间复杂度O(n).会占用额外的空间.

解法一代码:

#include <iostream>
#include <stdlib.h>
using namespace std; inline int my_rand(int low, int high)
{
int size = high - low + ;
return low + rand() % size;
}
int partition(int a[], int low, int high)
{
int val = a[low]; while(low<high)
{
while( (low<high) && (a[high]>=val) )
high--; a[low] = a[high];
while( (low<high) && (a[low] <= val) )
low++;
a[high] = a[low];
}
a[low] = val;
return low;
}
void swap(int *a,int i,int j)
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
bool rand_select(int array[], int left, int right, int k)
{
//第k 小元素,实际上应该在数组中下标为 k-1
if (k- > right || k- < left)
return false ; if(left<right)
{
//随机从数组中选取枢纽元元素
int index = my_rand(left, right);
swap(array,index,left); int pos = partition(array , left, right);
if(pos == k-)
return true ;
else if (pos > k-)
return rand_select(array , left, pos-, k);
else return rand_select(array, pos+, right, k);
}
else
return true ;
}
int main()
{
int array1[] = {, , , , , , , , , }; int numOfArray = sizeof (array1) / sizeof( int);
for(int i=; i<numOfArray; i++)
cout << array1[i] << " ";
cout << endl; int K = ;
bool flag = rand_select(array1, , numOfArray-, K); if(flag)
{
cout << "最小的" << K << "个数为:";
for(int i=; i<K; i++)
cout << array1[i] << " ";
cout << endl;
}
return ;
}

解法二代码:

//从头实现一个最大堆需要一定的代码,可以采用c++中的红黑树来实现。
//其中set和multiset都是基于红黑树实现的,后者可以支持数组中有重复
#include <iostream>
#include <set>
#include <vector> using namespace std; typedef multiset<int,greater<int>> intSet;
typedef multiset<int,greater<int>>::iterator setIterator; void getLeastNumbers(const vector<int> &data,intSet &leastNumbers,int k); int main(void)
{
int a[] = {,,,,,,,};
const vector<int> data(a,a+);//8不是7 intSet leastNumbers;
int k = ; getLeastNumbers(data,leastNumbers,k); cout << "最小的" << k << "个数为:";
setIterator iter = leastNumbers.begin();
for(;iter!=leastNumbers.end();++iter)
cout << *iter << " ";
cout << endl;
return ;
}
void getLeastNumbers(const vector<int> &data,intSet &leastNumbers,int k)
{
leastNumbers.clear(); if(k< || k>data.size())
return ; vector<int>::const_iterator iter = data.begin();
for(;iter != data.end();++iter)
{
if(leastNumbers.size() < k)
leastNumbers.insert(*iter);
else
{
setIterator iterGreatest = leastNumbers.begin();
if(*iter < *iterGreatest)
{
leastNumbers.erase(*iterGreatest);
leastNumbers.insert(*iter);
}
}
}
}

查找最小的k个元素 【微软面试100题 第五题】的更多相关文章

  1. 查找最小的k 个元素之C#算法实现

    紧接着上一篇微软编程面试100题,这次想解决的是查找最小的K个元素,题目是:输入n 个整数,输出其中最小的k 个.例如输入1,2,3,4,5,6,7 和8 这8 个数字,则最小的4 个数字为1,2,3 ...

  2. 【编程题目】查找最小的 k 个元素

    5.查找最小的 k 个元素(数组)题目:输入 n 个整数,输出其中最小的 k 个.例如输入 1,2,3,4,5,6,7 和 8 这 8 个数字,则最小的 4 个数字为 1,2,3 和 4. 算法里面学 ...

  3. 查找最小的K个元素,使用最大堆。

    查找最小的K个元素,使用最大堆,具体代码如下: #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace st ...

  4. 【Data Structure & Algorithm】 查找最小的k个元素

    查找最小的k个元素 题目:输入n个整数,输出其中最小的k个. 例如输入1, 2, 3, 4, 5, 6, 7和8这八个数字,则最小的4个数字为1, 2, 3和4. 分析:这道题最简单的思路是把输入的n ...

  5. 程序员面试50题(1)—查找最小的k个元素[算法]

    题目:输入n个整数,输出其中最小的k个.例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 分析:这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前面的k个数 ...

  6. 5.查找最小的k个元素[Kmin]

    [题目] 输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. [分析] 这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前 ...

  7. 5.查找最小的k个元素(数组)

    题目: 输入n个整数,输出其中最小的k个,例如输入1,2,3,4,5,6,7,8这8个数,则最小的4个是1,2,3,4(输出不要求有序) 解: 利用快速排序的partition,算导上求第k大数的思想 ...

  8. 查找最小的k个元素

    题目:输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 两种思路,无非就是时间与空间的妥协. 限制空间的时候要对原数组进行排序, ...

  9. IT公司100题-5-查找最小的k个元素

    问题描述: 输入n 个整数,输出其中最小的k 个. 例如输入8, 7, 6, 5, 4, 3, 2, 1这8 个数字,则最小的3 个数字为3, 2, 1.   分析: 时间复杂度O(nlogn)方法: ...

随机推荐

  1. 【踩坑】Nginx上配置ssl证书实现https访问

    昨天开始为域名挂上ssl证书,使得可以以https去访问服务器.按照网上所介绍的配置Nginx,然而一直访问不了网站. 第二天排查了一早上,发现不单要配置Nginx,阿里云上安全组要开启443端口,并 ...

  2. eclipse中安装lombok插件

    一:下载lombok 下载地址:https://projectlombok.org/downloads/lombok.jar 或者访问官网下载  https://projectlombok.org/ ...

  3. 邮箱/邮件地址的正则表达式及分析(JavaScript,email,regex)

    简言 在做用户注册时,常会用到邮箱/邮件地址的正则表达式.本文列举了几种方案,大家可以根据自己的项目情况,选择最适合的方案. 方案1 (常用) 规则定义如下: 以大写字母[A-Z].小写字母[a-z] ...

  4. HDU 2147 kiki's game kiki的游戏(博弈,找规律)

    题意: 给一个有n*m 个格子的棋盘,将一个硬币放在右上角一格,每次可以往左/下/左下移动一格,碰到不能移动的局面者输. 思路: 找P/N状态.先将(n,1)归为P状态,那么能一步到达此位置的有3个位 ...

  5. 2017.10.5 QBXT 模拟赛

    题目链接 T1 从小到大排序,用sum记录前缀和,然后枚举1~n个数 ,如果当前的前缀和 + 1小于a[i]的话 那么 sum + 1永远不可能拼出来 直接输出sum + 1 ,否则统计前缀和.最后如 ...

  6. 洛谷 P1001 A+B Problem

    题目描述 输入两个整数a,b,输出它们的和(|a|,|b|<=10^9). 注意 1.pascal使用integer会爆掉哦! 2.有负数哦! 3.c/c++的main函数必须是int类型,而且 ...

  7. 利用jieba第三方库对文件进行关键字提取

    已经爬取到的斗破苍穹文本以TXT形式存储 代码 import jieba.analyse path = 'C:/Users/Administrator/Desktop/bishe/doupo.text ...

  8. 关于日志造成的频繁的IO

    记录日志可能消耗大量的IO [Q] 每次写入都是一个IO操作 即使是同一个文件 两次写入也要打开两次IO操作 [F] 设想有这样一个扩展  把php中要记录的日志 用文件名 和 内容的方式记录在内存中 ...

  9. CDOJ 490 UESTC 490 Swap Game(思路,逆序对)

    题意:有两种颜色的小球形成环,求最小交互次数使球相连. 题解:先解决另一个简单的问题,如果是一个链,把红球标记为1,蓝球标记为0,要排成升序需要多少次交换呢?答案是逆序对总数,原因是一次交互最多消除一 ...

  10. [神经网络]一步一步使用Mobile-Net完成视觉识别(五)

    1.环境配置 2.数据集获取 3.训练集获取 4.训练 5.调用测试训练结果 6.代码讲解 本文是第五篇,讲解如何调用测试训练结果. 上一篇中我们输出了训练的模型,这一篇中我们通过调用训练好的模型来完 ...