方法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. node.js应用Redis数据库

    node.js下使用Redis,首先: 1.有一台安装了Redis的服务器,当然,安装在本机也行 2.本机,也就是客户端,要装node.js 3.项目要安装nodejs_redis模块 注意第 3 点 ...

  2. hdu 3038 How Many Answers Are Wrong ( 带 权 并 查 集 )

    How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  3. Sudoku Solver [LeetCode]

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  4. 创建PO/SO

    IF P_ZY EQ 'X'."直营订单 调拨单 PERFORM FRM_INIT_PO_HEADER. PERFORM FRM_INIT_PO_ITEM. PERFORM FRM_INIT ...

  5. 位运算取第一个非0的位 r & (~(r-1))

    Single Number III Given an array of numbers nums, in which exactly two elements appear only once and ...

  6. eval()函数使用

    条件:有数据集data[indx],数据集内含有对象data[index].obj1.pama1. 说明:传入参数为var str = 'obj1.pama1',要求取得data[index].obj ...

  7. [转载]Windows 7笔记本创建wifi热点供手机上网教程

    用智能手机的朋友会发现这样一个问题,智能手机比普通手机上网更耗流量.这是因为智能手机应用(软件)丰富,而且大部分应用都会自动联网.为此,许多人每月包了上百M的流量套餐,但用的时候还是小心翼翼,生怕流量 ...

  8. ANGULAR JS PROMISE使用

    Promise是一种模式,以同步操作的流程形式来操作异步事件,避免了层层嵌套,可以链式操作异步事件. 我们知道,在编写javascript异步代码时,callback是最最简单的机制,可是用这种机制的 ...

  9. linux percona-toolkit的安装

    percona-toolkit是一套linux下的工具集,我们需要使用到 pt-query-digest 对mysql慢日志查询来做分析. 1.下载 http://www.percona.com/do ...

  10. VS2003编译后的网站如何修改代码

    VS2003编译后的网站,如果没有源代码,而要修改里面的代码时,可以以以下方式解决: 反编译dll,把找出cs代码文件,然后重新建一个类项目,把此文件中的代码修改后重新生成dll,放在编译的网站中的b ...