剑指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