剑指offer二十九---最小的k个数

Markdown在线编辑器 - www.MdEditor.com

1.方法一:借助辅助数组存储k个最小的数

思想

存着最小k个数的数组,内部有序,遍历所有元素,和辅助数组中最大的比,只要小就替换辅助数组中的最大元素,然后再排序

代码

  1. // 使用辅助数组来实现
  2. vector<int> FuZhu(vector<int> a,int k) {
  3. vector<int> result;
  4. if(a.size() < k || k == 0) return result;
  5. if (a.empty()) {
  6. return result;
  7. }
  8. result.push_back(a[0]);
  9. for (int i = 1; i < a.size(); i++) {
  10. if (result.size() == k) {
  11. sort(result.begin(), result.end());
  12. if (a[i] < *(result.end()-1)) {
  13. result.pop_back();
  14. result.push_back(a[i]);
  15. }
  16. } else {
  17. result.push_back(a[i]);
  18. }
  19. }
  20. //时间复杂度
  21. return result;
  22. }
  23. vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
  24. return FuZhu(input, k);
  25. }

2.方法二:借助快速排序找到k的位置

思想

快速排序可以保证k左边的都小,右边都大,当基准元素位置==k个数时,输出前k个即可。
不用排两边,只要照着k在的那一侧即可

代码

  1. intOnce(vector<int>&a,int start,intend){
  2. int mark = start;
  3. int tmp =0;
  4. for(int i = start +1; i <=end; i++){
  5. if(a[start]> a[i]){
  6. mark++;
  7. tmp = a[i];
  8. a[i]= a[mark];
  9. a[mark]= tmp;
  10. }
  11. }
  12. tmp = a[mark];
  13. a[mark]= a[start];
  14. a[start]= tmp;
  15. return mark;
  16. }
  17. void kuaisu(vector<int>&a,int k,int start,intend){
  18. int i =Once(a, start,end);
  19. if(k == i){
  20. return;
  21. }
  22. // 这次分完位置在i,和k去比较
  23. if(i > k){
  24. kuaisu(a, k,0, i -1);
  25. }
  26. else{
  27. kuaisu(a, k, i +1,end);
  28. }
  29. }
  30. // 借鉴快速排序实现
  31. vector<int>GetLeastNumbers_Solution(vector<int> input,int k){
  32. //找到k的位置就行
  33. vector<int> result;
  34. if(k > input.size())return result;// 找不到k位置
  35. if(input.empty()){
  36. return result;
  37. }
  38. // 让我们开始快速排序
  39. kuaisu(input, k,0, input.size()-1);
  40. // 把前k个数存入result
  41. for(int i =0; i < k; i++){
  42. result.push_back(input[i]);
  43. }
  44. return result;
  45. }

原文地址:https://www.cnblogs.com/linxuesong/p/12173291.html

时间: 2024-10-08 07:22:32

剑指offer二十九---最小的k个数的相关文章

【剑指offer】 堆排序查找最小的K个数

上一篇 说了些堆的建立及其相关操作,这里看下用堆来解决数据量较大的时候,查找最小的k个数的情况.这里会用到上一篇中的函数. 我们先生存1千万个随机数,写到文件中: import random def randData(): with open('randint.txt', 'w') as fd: for i in range(1, 10000000): fd.write('%d ' %random.randint(1, 100)) if i % 100 == 0: fd.write('\r')

【剑指offer】40、最小的K个数

题目 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 思路一 基于partition,当 index正好为k的时候,就是第k大的数.时间复杂度O(n) 缺点:需要改变数组 class Solution { public: int Partition(vector<int>& input, int begin, int end) { int low = begin, high = end; int pivot =

剑指offer系列源码-最小的K个数

题目1371:最小的K个数 时间限制:1 秒内存限制:32 兆特殊判题:否提交:5175解决:1092 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1<=n,k<=200000),表示数组的长度. 第二行包含n个整数,表示这n个数,数组中的数的范围是[0,1000 000 000]. 输出: 对应每个测试案例,输出最小的k个数,并按从小到大顺序打印

剑指offer(29)最小的K个数

题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 题目分析 这题有两种方法来做. 第一种就是基于partition的方法,详见我的另一篇文章:基于快排思想查找第K大的数或第K小的数. 第二种就是利用一个长度为k的额外容器,来存储最小的K个数字.容器未满则填满,再添加数字是,将数字和容器的最大值比较,小的话就替换,大的话舍去. 这个容器要求可以直接得到最大值.能删除最大值,能添加值.那么很容易想到应该用最大堆当这个

剑指offer(二十九)之构建乘积数组

题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不能使用除法. 思路分析: 用两层FOR循环,当i=j时,不做处理,否则进行累乘.代码简单,一看就懂. 代码: <span style="font-family:SimSun;font-size:18px;">import java.util.ArrayList; public

剑指offer(二十三,二十四,二十五)最小的k个数,连续子数组的最大和,链表中环的入口节点

23:最小的k个数 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 简单题.... function GetLeastNumbers_Solution(input, k) { if(k>input.length) return []; let ans = []; input = input.sort(); //console.log(input.join("").slice(0,4).split

剑指offer(五十九)之二叉搜索树的后序遍历序列

题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 思路分析:BST的后序序列的合法序列是,对于一个序列S,最后一个元素是x (也就是根),如果去掉最后一个元素的序列为T,那么T满足:T可以分成两段,前一段(左子树)小于x,后一段(右子树)大于x,且这两段(子树)都是合法的后序序列. public class Solution { public boolean VerifySquenceOfBST(

剑指offer(二十八)之丑数

题目描述 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 思路分析: 1.首先,丑数都是由前5个丑数1,2,3,4,5乘以因子2,3,5才得到的. 2.这里将得到的丑数都存放在数组中.分析一下得到第6个丑数的过程,其他丑数类比. 3.1 将前5个丑数乘以2,然后与第5个丑数进行比较,找出第一个乘以2大于第5个丑数的丑数,将其放在min2中. 3.2 将前5个丑数乘以

剑指offer(二十六)之数组中重复的数字

题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 思路一: 用冒泡的思想,当遇到相等的元素的时候,将它放到duplication[0]当中,并将标志tag,改为true <span style="font-family:SimSun;font-size:18px;&