题目链接

https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=13&tqId=11182&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题意

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

解题思路

法一:若可以修改输入数据:时间复杂度O(n)。

利用快排的partition数组。第一遍以后partion的范围要想清楚,"是一个小小的范围",这样才能实现时间复杂度O(n)。

注意:1、特判一定要全!2、瞎throw容易看不到真正的错误提示... 3、各种边界填写的变量要过脑子...

法二:若不可以修改输入数据,或是要处理海量数据(内存较小):时间复杂度O(nlogk),内存要求可容纳大小为k的数组即可。

  • 可以维护一个大小为k的数组。
  • 容器满了后,每次再来一个数,若大于容器内最大值,则删除、插入新值(即替换),若小于容器内最大值,则忽略。
  • 最终得到的数组k即是最小的k个

使用红黑树实现以上算法。

特别地,由于直接替换节点可能破坏红黑树的结构,所以红黑树不支持直接改变元素值,必须要删除旧值、插入新值来实现。

相关知识

红黑树
  • 红黑树是特殊的二叉查找树,红黑节点保证最长路径<=2*最短路径。红黑树是自动有序的。

  • 红黑树不严格满足二叉平衡树(AVL)左右子树高度最多相差1的条件。?具体

  • 红黑树的查找、插入、删除时间复杂度都是O(logk)。?具体

  • STL中的set和multiset都是用红黑树实现,其中multiset可有重复元素。

比较仿函数greater 与less (即可以当作函数一样使用)
  • typedef multiset<int,greater<int>> intSet中,greater实质是一个结构体,greater表示内置类型从大到小排序,less表示内置类型从小到大排序。它们也可以用作sort函数的比较器。
  • set与multiset中默认使用less,即由小到大排序。
最大堆

最大堆中,根结点的值总是大于它的子树中任意节点的值。

得到最大值O(1)、插入、删除时间复杂度都是O(logk)。

代码

法一代码

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> minNums;
if(input.size()!=0&&k>=1&&k<=input.size()){//!!!写全
size_t beg=0;
size_t end=input.size()-1;
size_t index=partition(input,beg,end);//
while(index!=k-1){//
if(index<k-1){
beg=index+1;//
index=partition(input,beg,end);//
}
else{
end=index-1;//
index=partition(input,beg,end);//
}
}
for(int i=0;i<k;i++){
minNums.push_back(input[i]);
}
}
return minNums;
}
private:
size_t partition(vector<int> &input,size_t beg,size_t end){
if(!input.size()||end<beg||beg<0){
throw "input error!";
}
size_t index=random(beg,end);
swap(input[index],input[beg]);//
int temp=input[beg]; size_t i=beg;
size_t j=end;
while(i<j){
while(i<j&&input[j]>=temp){
--j;
}
if(i!=j){
input[i]=input[j];
++i;
}
while(i<j&&input[i]<=temp){
++i;
}
if(i!=j){
input[j]=input[i];
--j;
}
}
input[i]=temp;
return i;
} void swap(int& a,int& b){
int temp=a;
a=b;
b=temp;
} size_t random(size_t beg,size_t end){
if(end<beg){
throw "input error!";
}
srand((unsigned) time(0));
return beg+rand()%(end-beg+1);
}
};

法二代码

class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> minVec;
typedef multiset<int,greater<int>> intSet;
intSet minSet;
if(input.size()&&k>0&&k<=input.size()){
for(auto it=input.begin();it!=input.end();++it){
if(minSet.size()!=k){
minSet.insert(*it);
}
else{
if(*minSet.begin()>*it){
minSet.erase(minSet.begin());
minSet.insert(*it);
}
}
}
}
for(auto it=minSet.begin();it!=minSet.end();++it){
minVec.push_back(*it);
}
return minVec;
}
};

[剑指Offer]40-最小的k个数的更多相关文章

  1. 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序

    剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...

  2. 剑指 Offer 40. 最小的k个数

    剑指 Offer 40. 最小的k个数 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:ar ...

  3. 【Java】 剑指offer(40) 最小的k个数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7 ...

  4. 每日一题 - 剑指 Offer 40. 最小的k个数

    题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 快排 难易程度:中等 题目描述: 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3. ...

  5. 【剑指Offer】最小的K个数 解题报告(Python)

    [剑指Offer]最小的K个数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题目 ...

  6. Go语言实现:【剑指offer】最小的K个数

    该题目来源于牛客网<剑指offer>专题. 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. Go语言实现: fu ...

  7. 剑指OFFER之最小的K个数(九度OJ1371)

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1< ...

  8. 《剑指offer》最小的k个数

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

  9. 剑指Offer 29. 最小的K个数 (其他)

    题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 题目地址 https://www.nowcoder.com/prac ...

  10. 【剑指offer】最小的K个数

    一.题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 二.思路: 一群大牛在讨论用噼里啪啦各种排序,复杂度一般也都是O ...

随机推荐

  1. Python文件夹与文件的操作(转)

    最近在写的程序频繁地与文件操作打交道,这块比较弱,还好在百度上找到一篇不错的文章,这是原文传送门,我对原文稍做了些改动. 有关文件夹与文件的查找,删除等功能 在 os 模块中实现.使用时需先导入这个模 ...

  2. C++复习:异常

    异常处理机制专题 前言 1)异常是一种程序控制机制,与函数机制独立和互补     函数是一种以栈结构展开的上下函数衔接的程序控制系统,异常是另一种控制结构,它依附于栈结构,却可以同时设置多个异常类型作 ...

  3. centOS6.6网络设置

    linux的网卡IP地址是存放在文件中的,这个配置文件在/etc/sysconfig/network-scripts下, 名称分别为ifcfg-eth0,ifcfg-eth1等 如果你只有一块网卡,就 ...

  4. 【转】WinDbg调试器:启动程序时自动连接调试器方法

    当我们调试服务进程或子进程时,无法直接用调试加载进程的方式启动,此时需要在启动程序时自动连接调试器方法: 第一步:注册表展开到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft ...

  5. C#图像处理:截图程序(包含鼠标)

    截图后在picbox中显示,用定时器定时每毫秒截图一次,在picbox上显示就有动画效果.代码: [DllImport("user32.dll")] static extern b ...

  6. Linux非常有用的命令

    <判断用户是否存在,如不存在则新建> user=`grep '^admin:' /etc/passwd`if [ -z "$user" ];then groupadd ...

  7. java 导包

    在maven 中搜索相关模块依赖 http://mvnrepository.com/artifact/org.apache.spark/spark-mllib_2.10/1.0.0 dependenc ...

  8. 支付宝支付Java代码

    支付宝调用流程 开发前的准备工作 配置应用网关 应用网关里面填写的值就是商户后台的异步回调地址.也就是在支付宝付完款之后,由支付宝调用商户,便于商户验证订单各信息和更新订单状态 授权回调地址 授权回调 ...

  9. 04_web基础(四)之servlet详解

    16.17.18.servlet生命周期 javax.servlet.Servlet接口方法:public String getServletInfo():获取Servlet相关信息(作者,版权,版本 ...

  10. Loading AssetBundle Manifests

    [Loading AssetBundle Manifests] AssetBundle Manifest 可以用于获取dependency. AssetBundle assetBundle = Ass ...