这是在面试常遇到的topk问题。

题目描述:

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

解题思路:

思路一:用快排对数组做一次排序,输出前k个。这种方法会改变原数组排列,复杂度为O(nlogn)。

思路二:基于partition思想,进行一次快速排序用哨兵数分割数组中的数据。由于partition每次将数组分成两段,左半部分小于关键字,右半部分大于关键字。可以递归做partition,关键字位置,若关键字位置等于k-1,则输出左半部分。否则,若大于k-1,则对左半部分做partition;若小于k-1,则往后拓展一位。

这种方法同样会改变原数组排列,算法复杂度为O(n)。

思路三:大顶二叉堆。基于红黑树(???)思想,首先创建一个大小为k的容器,用来存储最小的k个数字;然后每次从输入的n个整数中输入一个数,如果容器中已有的数字少于k个,则直接把读入的整数放入容器;如果容器中已有k个数字,则不能再插入新的数字而只能替换已有的数字。替换的原则:如果待插入的值m比容器中的最大值n小,则m替换n;如果待插入的值m比容器中的最大值n大,则保持不变。(在k个整数中找到最大值、删除容器最大值、插入一个新的数字)

可以用优先队列完成,设定一个大小为k的优先队列,将数组一次放进去,由于优先队列的排列是从大到小,所以每次当新的数进队时,当队列已满,就做出队操作,每次出队的都是最大的元素。因此最后保留在队列当中的就是最小的k个数。算法复杂度O(nlogk),不会改变原数组的排列。该方法适合处理海量数据。

代码:

思路一:

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(input.size()== || k<)
return res;
if(input.size() < k)
return res;
sort(input.begin(), input.end());
for(int i=; i<k; i++)
res.push_back(input[i]);
return res;
}
};

思路二:

class Solution {
public:
int partition(vector<int>& a, int low, int high) //要改变vector,必须传入地址
{
int temp;
int base = low;
temp = a[low];
while(low<high)
{
while(a[high] >= temp && low<high)
high--;
while(a[low] <= temp && low<high)
low++;
if(low<high)
swap(a[low], a[high]);
}
swap(a[base], a[low]);
return low;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(input.size()== || k< || input.size() < k)
return res;
int low = ;
int high = input.size()-;
int index = partition(input, low, high);
while(index != (k-))
{
if(index > (k-))
{
high = index-;
index = partition(input, low, high);
}
else
{
low = index+;
index = partition(input, low, high);
}
}
for(int i=; i<k; i++)
res.push_back(input[i]);
return res;
}
};

思路三:

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(input.size()== || k< || input.size() < k)
return res;
priority_queue<int> q;
for(int i=; i<input.size(); i++)
{
q.push(input[i]);
if(q.size()>k)
{
q.pop();
}
}
while(!q.empty())
{
res.push_back(q.top());
q.pop();
}
return res;
}
};

剑值offer:最小的k个数的更多相关文章

  1. 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)

    注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...

  2. 剑指Offer——最小的K个数

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 分析: 建一个K大小的大根堆,存储最小的k个数字. 先将K个数进堆 ...

  3. python剑指offer最小的K个数

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 思路: 使用快排中的partition思想. ①我们设定part ...

  4. 剑指 Offer——最小的 K 个数

    1. 题目 2. 解答 2.1. 方法一--大顶堆 参考 堆和堆排序 以及 堆的应用,我们将数组的前 K 个位置当作一个大顶堆. 首先建堆,也即对堆中 [0, (K-2)/2] 的节点从上往下进行堆化 ...

  5. 用js刷剑指offer(最小的K个数)

    题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 牛客网链接 js代码 function GetLeastNumbe ...

  6. 剑指offer--10.最小的K个数

    边界判断,坑了一下 ----------------------------------------------- 时间限制:1秒 空间限制:32768K 热度指数:375643 本题知识点: 数组 ...

  7. 剑指Offer-29.最小的K个数(C++/Java)

    题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 分析: 最先想到的是将数组升序排列,返回前k个元素.不过排序的话效率 ...

  8. 剑指:最小的k个数

    题目描述 输入 n 个整数,找出其中最小的 K 个数.例如输入 4,5,1,6,2,7,3,8 这 8 个数字,则最小的 4 个数字是 1,2,3,4. 解法 解法一 利用快排中的 partition ...

  9. 2-剑指offer: 最小的K个数

    题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 代码: // 这种topN问题比较常见的是使用堆来解决,最小的k个 ...

  10. 剑指Offer28 最小的K个数(Partition函数应用+大顶堆)

    包含了Partition函数的多种用法 以及大顶堆操作 /*********************************************************************** ...

随机推荐

  1. IO流(字节流,字符流,缓冲流)

    一:IO流的分类(组织架构) 根据处理数据类型的不同分为:字节流和字符流 根据数据流向不同分为:输入流和输出流   这么庞大的体系里面,常用的就那么几个,我们把它们抽取出来,如下图:   二:字符字节 ...

  2. 【NOIP2017D2T3】列队

    Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵.Sylvia所在的方阵中有n × m名学生,方阵的行数为 n, ...

  3. C#常见委托のdelegate定义,Func,Action,Predicate总结

    委托,顾名思义,就是让其他代理,本质就是为具有共性方法组定义一个方法模板:(交流可以加qq群:435226676) 委托常见的方式有一般委托显示定义,Func<T,TResult> (T, ...

  4. map && multimap

    map map 的意思是映射.用法一般是     map<char, int>mp 按照我的理解,map 类似于一个高级的数组.前面的数据类型 char 相当于下脚标,而数组元素的值就对应 ...

  5. Java中集合删除元素时候关于ConcurrentModificationException的迷惑点

    下面的示例来至于阿里巴巴Java开发手册的集合处理部分的第7条: 运行如下代码,会发现正确运行. public static void hasNotExcption() { List<Strin ...

  6. php单例模式实现对象只被创建一次

    这是我在php面试题中遇到的一道试题,单例模式按字面来看就是某一个类只有一个实例,这样做的好处还是很大的,比如说数据库的连接,我们只需要实例化一次,不需要每次都去new了,这样极大的降低了资源的耗费. ...

  7. go标准库的学习-time

    参考https://studygolang.com/pkgdoc 导入形式: import "time" time包提供了时间的显示和测量用的函数.日历的计算采用的是公历. 1&g ...

  8. 深入springboot原理——动手封装一个starter

    从上一篇文章<深入springboot原理——一步步分析springboot启动机制(starter机制)> 我们已经知道springboot的起步依赖与自动配置的机制.spring-bo ...

  9. lombok的使用和原理

    一.项目背景 在写Java程序的时候经常会遇到如下情形: 新建了一个Class类,然后在其中设置了几个字段,最后还需要花费很多时间来建立getter和setter方法 lombok项目的产生就是为了省 ...

  10. Qt+Qgis二次开发:在状态条显示当前鼠标坐标

    1  概述 鼠标在地图上移动,需要实时获取当前坐标位置.2 原理 从当前位置获取视口坐标后,实时转换为地图坐标.3 方法 处理鼠标位置,必须获取鼠标的当前坐标.但是Qt的鼠标事件由QgsMapCanv ...