方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn);

方法2:维护一个容量为K的最大堆(《算法导论》第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如果大于最大元素则忽略,如果小于最大元素则将次元素送入堆中,并将堆的最大元素删除,调整堆的结构;

方法3:使用快速排序的原理,选择出数组中第K大的元素,select(a[], k, low, high)

  • 选取数组中a[high]为基准,将数组分割为A1和A2,A1中的元素都比a[high]小,A[2]中的元素都比a[high]大,将a[high]放到合适的位置;
  • 如果k小于a[high]实际位置的index,则递归调用此函数select(a[], k, low, index - 1);
  • 如果k大于a[high]实际位置的index,则递归调用此函数selet(a[], k, index + 1, high);
  • 如果k等于a[hign]实际位置的index,则此时的index位置之前的数即为数组中最小的k个数;
  1. /**
  2. * Created by Administrator on 2014/12/8.
  3. * 输入N个整数,输出最小的K个
  4. */
  5. import java.util.ArrayList;
  6. import java.util.Arrays;
  7. import java.util.Scanner;
  8.  
  9. public class MinKArray {
  10. /* 用二叉树表示一个堆 */
  11. private class Heap {
  12. private Node root;
  13. private class Node {
  14. int key;
  15. Node left;
  16. Node right;
  17. Node(int key) {
  18. this.key = key;
  19. }
  20. }
  21.  
  22. /* 建立最大堆,将元素插入到堆的合适位置 */
  23. public void put(int key) {
  24. root = put(root, key);
  25. }
  26.  
  27. private Node put(Node x, int key) {
  28. if (x == null)
  29. return new Node(key);
  30. int cmp = key - x.key;
  31. if (cmp > 0) {
  32. int tmp = x.key;
  33. x.key = key;
  34. key = tmp;
  35. x.right = put(x.right, key);
  36. } else if (cmp < 0) {
  37. x.left = put(x.left, key);
  38. }
  39. return x;
  40. }
  41.  
  42. public void deleteMax() {
  43. root = deleteMax(root);
  44. }
  45.  
  46. private Node deleteMax(Node x) {
  47. if (x == null)
  48. return null;
  49. if ((x.left == null) && (x.right != null)) {
  50. int tmp = x.key;
  51. x.right.key = x.key;
  52. x.key = tmp;
  53. x.right = deleteMax(x.right);
  54. } else if ((x.right == null) && (x.left != null)) {
  55. int tmp = x.key;
  56. x.left.key = x.key;
  57. x.key = tmp;
  58. x.left = deleteMax(x.left);
  59. } else if ((x.left == null) && (x.right == null)) {
  60. x = null;
  61. } else {
  62. int cmp = x.left.key - x.right.key;
  63. if (cmp >= 0) {
  64. int tmp = x.key;
  65. x.key = x.left.key;
  66. x.left.key = tmp;
  67. x.left = deleteMax(x.left);
  68. } else {
  69. int tmp = x.key;
  70. x.key = x.right.key;
  71. x.right.key = tmp;
  72. x.right = deleteMax(x.right);
  73. }
  74. }
  75. return x;
  76. }
  77.  
  78. public void printHeap(Node x) {
  79. if (x == null)
  80. return;
  81. System.out.print(x.key + " ");
  82. printHeap(x.left);
  83. printHeap(x.right);
  84. }
  85. }
  86.  
  87. /* 使用一般的排序算法,然后顺序输出前K个元素 */
  88. public int[] minKArray1(int[] a, int k) {
  89. Arrays.sort(a);
  90. for (int i = 0; i < k; i++) {
  91. System.out.print(a[i] + " ");
  92. }
  93. return Arrays.copyOfRange(a, 0, k);
  94. }
  95.  
  96. /* 求出数组中第K大的元素,然后顺序遍历所有元素 */
  97. public int[] minKArray2(int[] a, int k) {
  98. minKArray2(a, k, 0, a.length - 1);
  99. return a;
  100. }
  101.  
  102. /* 利用快速排序的原理,以a[high]为基准,将a[high]放到相应的位置
  103. * 左边的都比它小,右边的都比它大 */
  104. private void minKArray2(int[] a, int k, int low, int high) {
  105. if (low <= high) {
  106. int l = low, r = high - 1;
  107. int x = a[high];
  108. for (int i = low; i < high; i++) {
  109. if (l <= r) {
  110. if (a[l] > x) {
  111. int tmp = a[r];
  112. a[r] = a[l];
  113. a[l] = tmp;
  114. r--;
  115. }
  116. if (a[l] <= x) {
  117. l++;
  118. }
  119. }
  120. }
  121. int tmp = a[l];
  122. a[l] = a[high];
  123. a[high] = tmp;
  124.  
  125. if (l < k) {
  126. minKArray2(a, k, l + 1, high);
  127. } else if (l > k) {
  128. minKArray2(a, k, low, l - 1);
  129. } else {
  130. for (int i = 0; i < k; i++) {
  131. System.out.print(a[i] + " ");
  132. }
  133. }
  134. }
  135. }
  136.  
  137. /* 维护一个容量为K的最大堆,《算法导论》第6章堆排序 */
  138. public int[] minKArray3(int[] a, int k) {
  139. Heap h = new Heap();
  140. for (int i = 0; i < k; i++) {
  141. h.put(a[i]);
  142. }
  143. for (int i = k; i < a.length; i++) {
  144. if (a[i] >= h.root.key) {
  145. continue;
  146. } else {
  147. h.put(a[i]);
  148. h.deleteMax();
  149. }
  150. }
  151. h.printHeap(h.root);
  152. return a;
  153. }
  154.  
  155. public static void main(String[] args) {
  156. Scanner scan = new Scanner(System.in);
  157. ArrayList<Integer> array = new ArrayList<Integer>();
  158. while (scan.hasNext()) {
  159. array.add(scan.nextInt());
  160. }
  161. int[] a = new int[array.size()];
  162. for (int i = 0; i < a.length; i++) {
  163. a[i] = array.get(i);
  164. }
  165. MinKArray mka = new MinKArray();
  166. mka.minKArray1(a, 8);
  167. System.out.println();
  168. mka.minKArray2(a, 8);
  169. System.out.println();
  170. mka.minKArray3(a, 8);
  171. System.out.println();
  172. }
  173. }

求一个数组中最小的K个数的更多相关文章

  1. 【算法】数组与矩阵问题——找到无序数组中最小的k个数

    /** * 找到无序数组中最小的k个数 时间复杂度O(Nlogk) * 过程: * 1.一直维护一个有k个数的大根堆,这个堆代表目前选出来的k个最小的数 * 在堆里的k个元素中堆顶的元素是最小的k个数 ...

  2. [算法]找到无序数组中最小的K个数

    题目: 给定一个无序的整型数组arr,找到其中最小的k个数. 方法一: 将数组排序,排序后的数组的前k个数就是最小的k个数. 时间复杂度:O(nlogn) 方法二: 时间复杂度:O(nlogk) 维护 ...

  3. 小米笔试题:无序数组中最小的k个数

    题目描述 链接:https://www.nowcoder.com/questionTerminal/ec2575fb877d41c9a33d9bab2694ba47?source=relative 来 ...

  4. 求给定数据中最小的K个数

    public class MinHeap { /* * * Top K个问题,求给定数据中最小的K个数 * * 最小堆解决:堆顶元素为堆中最大元素 * * * */ private int MAX_D ...

  5. 《程序员代码面试指南》第八章 数组和矩阵问题 找到无序数组中最小的k 个数

    题目 找到无序数组中最小的k 个数 java代码 package com.lizhouwei.chapter8; /** * @Description: 找到无序数组中最小的k 个数 * @Autho ...

  6. 求数组中最小的k个数

    题目:输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. package test; import java.util.Arra ...

  7. 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆

    原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...

  8. [剑指offer]数组中最小的K个数,C++实现

    原创博文,转载请注明出处! http://github.com/wanglei5205 http://cnblogs.com/wanglei5205 # 题目 输入n个整数,找出其中最小的K个数.例如 ...

  9. 找到数组中最小的k个数

    /*输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字, 则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k = ...

随机推荐

  1. Azure平台 对Twitter 推文关键字进行实时大数据分析

    Learn how to do real-time sentiment analysis of big data using HBase in an HDInsight (Hadoop) cluste ...

  2. uploader上传

    综述 Uploader是非常强大的异步文件上传组件,支持ajax.iframe.flash三套方案,实现浏览器的全兼容,调用非常简单,内置多套主题支持和常用插件,比如验证.图片预览.进度条等. 广泛应 ...

  3. grouping sets,cube,rollup,grouping__id,group by

    例1: hive -e" select type ,status ,count(1) from usr_info where pt='2015-09-14' group by type,st ...

  4. QMessageBox中按钮的汉化

    方法一:直接添加汉语按钮: QMessageBox mess(QMessageBox::Question, "删除提示", "确认删除所选组件?", NULL) ...

  5. 集合框架,ArrayList和Vector的区别,让arrayList线程安全的几种方案

    boolean add(E e) 将指定的元素添加到此列表的尾部. void add(int index, E element) 将指定的元素插入此列表中的指定位置. boolean addAll(C ...

  6. SQL语句创建数据库,SQL语句删除数据库,SQL语句创建表,SQL语句删除表,SQL语句添加约束,SQL语句删除约束

    创建数据库: CREATE DATABASE Test --要创建的数据库名称 ON PRIMARY ( --数据库文件的具体描述 NAME='Test_data', --主数据文件的逻辑名称 FIL ...

  7. 问题解决The connection to adb is down, and a severe error has occured.

    遇到问题描述: 运行android程序控制台输出 [2013-06-25 11:10:32 - MyWellnessTracker] The connection to adb is down, an ...

  8. 详解Jquery和AngularJs,Servlet中jsonp解决跨域问题(转)

    众所周知,jsonp可以解决跨域问题,下面是我在查阅资料和实际项目使用后的一些总结. Jquery中jsonp的使用 //myUrl = "http://localhost:8090/api ...

  9. BZOJ1584 [Usaco2009 Mar]Cleaning Up 打扫卫生

    令$f[i]$表示以i为结尾的答案最小值,则$f[i] = min \{f[j] + cnt[j + 1][i]^2\}_{1 \leq j < i}$,其中$cnt[j + 1][i]$表示$ ...

  10. PHP多线程类

    <?php /** * @title: PHP多线程类(Thread) * @version: 1.0 * @author: phper.org.cn < web@phper.org.cn ...