方法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个数;
/**
* Created by Administrator on 2014/12/8.
* 输入N个整数,输出最小的K个
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner; public class MinKArray {
/* 用二叉树表示一个堆 */
private class Heap {
private Node root;
private class Node {
int key;
Node left;
Node right;
Node(int key) {
this.key = key;
}
} /* 建立最大堆,将元素插入到堆的合适位置 */
public void put(int key) {
root = put(root, key);
} private Node put(Node x, int key) {
if (x == null)
return new Node(key);
int cmp = key - x.key;
if (cmp > 0) {
int tmp = x.key;
x.key = key;
key = tmp;
x.right = put(x.right, key);
} else if (cmp < 0) {
x.left = put(x.left, key);
}
return x;
} public void deleteMax() {
root = deleteMax(root);
} private Node deleteMax(Node x) {
if (x == null)
return null;
if ((x.left == null) && (x.right != null)) {
int tmp = x.key;
x.right.key = x.key;
x.key = tmp;
x.right = deleteMax(x.right);
} else if ((x.right == null) && (x.left != null)) {
int tmp = x.key;
x.left.key = x.key;
x.key = tmp;
x.left = deleteMax(x.left);
} else if ((x.left == null) && (x.right == null)) {
x = null;
} else {
int cmp = x.left.key - x.right.key;
if (cmp >= 0) {
int tmp = x.key;
x.key = x.left.key;
x.left.key = tmp;
x.left = deleteMax(x.left);
} else {
int tmp = x.key;
x.key = x.right.key;
x.right.key = tmp;
x.right = deleteMax(x.right);
}
}
return x;
} public void printHeap(Node x) {
if (x == null)
return;
System.out.print(x.key + " ");
printHeap(x.left);
printHeap(x.right);
}
} /* 使用一般的排序算法,然后顺序输出前K个元素 */
public int[] minKArray1(int[] a, int k) {
Arrays.sort(a);
for (int i = 0; i < k; i++) {
System.out.print(a[i] + " ");
}
return Arrays.copyOfRange(a, 0, k);
} /* 求出数组中第K大的元素,然后顺序遍历所有元素 */
public int[] minKArray2(int[] a, int k) {
minKArray2(a, k, 0, a.length - 1);
return a;
} /* 利用快速排序的原理,以a[high]为基准,将a[high]放到相应的位置
* 左边的都比它小,右边的都比它大 */
private void minKArray2(int[] a, int k, int low, int high) {
if (low <= high) {
int l = low, r = high - 1;
int x = a[high];
for (int i = low; i < high; i++) {
if (l <= r) {
if (a[l] > x) {
int tmp = a[r];
a[r] = a[l];
a[l] = tmp;
r--;
}
if (a[l] <= x) {
l++;
}
}
}
int tmp = a[l];
a[l] = a[high];
a[high] = tmp; if (l < k) {
minKArray2(a, k, l + 1, high);
} else if (l > k) {
minKArray2(a, k, low, l - 1);
} else {
for (int i = 0; i < k; i++) {
System.out.print(a[i] + " ");
}
}
}
} /* 维护一个容量为K的最大堆,《算法导论》第6章堆排序 */
public int[] minKArray3(int[] a, int k) {
Heap h = new Heap();
for (int i = 0; i < k; i++) {
h.put(a[i]);
}
for (int i = k; i < a.length; i++) {
if (a[i] >= h.root.key) {
continue;
} else {
h.put(a[i]);
h.deleteMax();
}
}
h.printHeap(h.root);
return a;
} public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ArrayList<Integer> array = new ArrayList<Integer>();
while (scan.hasNext()) {
array.add(scan.nextInt());
}
int[] a = new int[array.size()];
for (int i = 0; i < a.length; i++) {
a[i] = array.get(i);
}
MinKArray mka = new MinKArray();
mka.minKArray1(a, 8);
System.out.println();
mka.minKArray2(a, 8);
System.out.println();
mka.minKArray3(a, 8);
System.out.println();
}
}

求一个数组中最小的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. python 练习 3

    #!/usr/bin/python # -*- coding: utf-8 -*- def z94(): #斐波那契数列 def filie(x): a,b,t=1,1,0 if x==1 or x= ...

  2. 输出有序数组的中两个元素差值为指定值diff的两个元素

    题目: 输出有序数组的中两个元素差值为指定值diff的两个元素. 思路: 这与输出两个元素的和的值为一定值类似,需要两个指针,不同的是:指针不是一左一右,而是一前一后. 如果差值等于diff,则返回: ...

  3. ABAP-smartform-一页3列的条码打印

    1.自建barcode: se73->System bar code->change->create->new input the name of the bar code y ...

  4. C#与Java中相等关系

    最近在学习java的语法,发现java中两个字符串某些情况下不能用==这个来判断,比如自己定义的类中有String属性,那么就不能用==判断两个是否相等.这才开始比较C#和Java在这里的区别,最后发 ...

  5. mvc+ef中比较数据

    例如:根据Para表中的type和paraid 字段进行比较 public class TypeComparer : IEqualityComparer<Para> { bool IEqu ...

  6. Error in Android Studio - "Default Activity Not Found"

    Make sure you have specified the default activity in your AndroidManisfest.xml file. Within your def ...

  7. OLAP 模型

    OLAP分析的基础是多维数据集,按照其数据存储格式的不同可以分为关系型OLAP(Relational OLAP,ROLAP)和多维型OLAP(Multidimensional OLAP,MOLAP). ...

  8. 25个有用和方便的 WordPress 速查手册

    如果你是一个 WordPress 编码器或开发人员,下载一些方便的 WordPress 备忘单寻找你的工作然后你在正确的地方.我们已经列出了25个有用的和方便的 WordPress 速查手册.Word ...

  9. div垂直居中的问题

    工作和面试时常常会遇到怎么设置div垂直居中与浏览器中:包括固定宽高和不固定宽高的 1.固定宽高的div垂直居中 宽高固定的div很容易设置让其垂直居中 <div class="cen ...

  10. mac 找文件

    如何找到 etc 方法1: ! D# D! s2 F" f 七度苹果电脑软件1.打开Finder,按快键盘 Command + Shift + G,即可调出 前往文件夹 ,也可以左上角 找到 ...