1. 题目

2. 解答

2.1. 方法一——大顶堆

参考 堆和堆排序 以及 堆的应用,我们将数组的前 K 个位置当作一个大顶堆。

首先建堆,也即对堆中 [0, (K-2)/2] 的节点从上往下进行堆化。第 K/2 个节点若有子节点,其左子节点位置应该为 2 * K/2 + 1 = K+1,而我们堆中的最大位置为 K-1,显然第 K/2 个节点是第一个叶子节点,不用堆化。

建完堆之后,我们顺序访问原数组 [k, n-1] 位置的元素,如果当前元素小于堆顶元素也就是位置为 0 的元素,那么删除堆顶元素并将当前元素插入堆中。

最后,堆中的 K 个元素即为所求。

  1. class Solution {
  2. public:
  3. vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
  4. if (k > input.size())
  5. {
  6. vector<int> result;
  7. return result;
  8. }
  9. Build_Heap_K(input, k);
  10. vector<int> result(input.begin(), input.begin()+k);
  11. return result;
  12. }
  13. void Build_Heap_K(vector<int> &input, int k)
  14. {
  15. // input 的 [0, k-1] 作为一个大小为 K 的大顶堆
  16. // 然后从上往下进行堆化
  17. // 也就是对堆中 [0, (k-2)/2] 的节点进行堆化
  18. for (int i = (k-2)/2; i >= 0; i--)
  19. Heapify(input, k, i);
  20. // 遍历 input 的 [k, n-1] 的元素
  21. // 如果某元素小于堆顶值,将其插入堆中
  22. // 也即将其替换为堆顶元素,堆化之
  23. for (int i = k; i < input.size(); i++)
  24. {
  25. if (input[i] < input[0])
  26. {
  27. input[0] = input[i];
  28. Heapify(input, k, 0);
  29. }
  30. }
  31. }
  32. void Heapify(vector<int> &input, int k, int i)
  33. {
  34. while(1)
  35. {
  36. int max_pos = i;
  37. if (2*i+1 < k && input[2*i+1] > input[max_pos])
  38. max_pos = 2 * i + 1;
  39. if (2*i+2 < k && input[2*i+2] > input[max_pos])
  40. max_pos = 2 * i + 2;
  41. if (max_pos == i)
  42. break;
  43. else
  44. {
  45. int temp = input[max_pos];
  46. input[max_pos] = input[i];
  47. input[i] = temp;
  48. }
  49. i = max_pos;
  50. }
  51. }
  52. };
2.2. 方法二——快排分治

可参考 LeetCode 215——数组中的第 K 个最大元素

快排的时候需要分区,分区点左边的元素都小于主元,分区点右边的元素都大于主元。如果分区后主元的位置恰好为 K,那左边正好是最小的 K 个数;如果大于 K,我们需要递归在左边找到第 K 个位置;如果小于 K,我们则需要递归在右边找到第 K 个位置。

  1. class Solution {
  2. public:
  3. vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
  4. int n = input.size();
  5. if (k > n)
  6. {
  7. vector<int> result;
  8. return result;
  9. }
  10. Quick_Sort(input, 0, n-1, k);
  11. vector<int> result(input.begin(), input.begin()+k);
  12. return result;
  13. }
  14. void Quick_Sort(vector<int> &input, int left, int right, int k)
  15. {
  16. if (left < right)
  17. {
  18. int pivot = input[right];
  19. int i = left;
  20. int j = left;
  21. for (; j < right; j++)
  22. {
  23. if (input[j] < pivot)
  24. {
  25. int temp = input[i];
  26. input[i] = input[j];
  27. input[j] = temp;
  28. i++;
  29. }
  30. }
  31. input[j] = input[i];
  32. input[i] = pivot;
  33. if (i == k) return;
  34. else if (i > k) Quick_Sort(input, left, i-1, k);
  35. else Quick_Sort(input, i+1, right, k);
  36. }
  37. }
  38. };

获取更多精彩,请关注「seniusen」!

剑指 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. 用js刷剑指offer(最小的K个数)

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

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

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

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

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

  7. 剑指:最小的k个数

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

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

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

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

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

随机推荐

  1. [LeetCode] 107. 二叉树的层次遍历 II

    题目链接 : https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/ 题目描述: 给定一个二叉树,返回其节点值自底 ...

  2. python是强语言还是弱语言?

    python是强语言还是弱语言,没有一个具体官方的说法 数据类型也就是变量类型,一般编程语言的变量类型可以分成下面两类. 静态类型与动态类型 静态类型语言:一种在编译期间就确定数据类型的语言.大多数静 ...

  3. SCUT - 485 - 质因数计数 - 原根

    https://scut.online/p/485 给定a和n,求有多少个质数p,满足n是使得a^n=1 mod p成立的最小正整数. 翻译:求有多少个质数p,使得a模p的阶delta_m(a)是n ...

  4. kafka复习(2)

    一.简介 --------------------------------------- 1.kafka是一个分布式的.可分区的.可复制的消息系统.它提供了消息系统的功能,但是有自己独特的设计. 2. ...

  5. IOS绘图详解(http://blog.163.com/wkyuyang_001/blog/static/10802122820133190545227/)

    14.1 Quartz概述 Quartz是Mac OS X的Darwin核心之上的绘图层,有时候也认为是CoreGraphics.共有两种部分组成Quartz: Quartz Compositor,合 ...

  6. hashlib模块和logging模块

    hashlib Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值: import hashlib m=hashli ...

  7. 图像描点标注-labelme的安装及使用

    1.直接使用pip安装lebelme pip install labelme 2.labelme的使用 找到labelme的安装路径,先找到python的安装路径如我的,C:\Users\Think\ ...

  8. 长沙理工大学第十二届ACM大赛-重现赛 D 小M和天平 (01背包)

    链接:https://ac.nowcoder.com/acm/contest/1/D 来源:牛客网 小M和天平 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K,其他语言 ...

  9. Insomni'hack teaser 2019 - Pwn - 1118daysober

    参考链接 https://ctftime.org/task/7459 Linux内核访问用户空间文件:get_fs()/set_fs()的使用 漏洞的patch信息 https://maltekrau ...

  10. GUI学习之三十一—QLabel学习总结

    前面所有的控件都是归于输入控件的,下面我们要总结下展示控件的用法.首先要将的就是最常用的QLabel. 一.描述  标签控件(QLabel)提供了文本或图像显示的功能,可以用来显示 普通文本 数字 富 ...