您的位置:首页 > 其它

无序数组中最小的k个数

2016-04-07 19:04 113 查看
对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的k个数,顺序与原数组中元素顺序一致。

给定一个整数数组A及它的大小n,同时给定k,请返回其中最小的k个数。

测试样例:

[1,2,4,3],4,2

返回:[1,2]

import java.util.*;

/**
* 无序数组中最小的k个数
*
* @author 过路的守望
*
*/
public class KthNumbers {
public static void main(String[] args) {
int[] A = { 16623, 11263, 27224, 1374, 28243, 12025, 35595, 23825,
30591, 17911, 13499, 33856, 17145, 41898, 25686, 37261, 4025,
27318, 5327, 27685, 19662, 15902, 34683, 2807, 19737, 29773,
20816, 30378, 6204, 7959, 11453, 42194, 40811, 38037, 23309,
27252, 36361, 26453, 22951, 24705, 25188, 37521, 12909, 40001,
39741, 9820, 8272, 19383, 27274, 14974, 24726, 39710, 1941,
32660, 14351, 23254, 41058, 20144, 10661, 4896, 39424, 29002,
31492, 32478, 33392, 18897, 6966, 12929, 23049, 8438, 41087,
3078, 15539, 20410, 34508, 38646, 22596, 9373, 21788, 14473,
33444, 785, 25974 };
System.out.println(Arrays.toString(new KthNumbers().findKthNumbers(A,
84, 31)));
}

public int[] findKthNumbers(int[] A, int n, int k) {
n = A.length;
/*
* p为数组中第k大的数
*/
int p = getKthNumberByHeapSort(A, k);
int[] result = new int[k];
int pos = 0;
System.out.println(p);
for (int i = 0; i < n; i++) {
if (A[i] <= p) {
result[pos++] = A[i];
}
}
return result;
}

/**
* 取数组前k个元素作为初始堆元素
*
* @param A
* @param k
* @return
*/
public int getKthNumberByHeapSort(int[] A, int k) {
int[] heap = new int[k];
heap = Arrays.copyOf(A, k);
/*
* 建堆
*/
buildHeap(heap, k);
/*
* 将数组后n-k个元素与堆顶元素比较,若比其小,则赋值给堆顶元素后执行下滤操作. 时间复杂度
*/
for (int i = k; i < A.length; i++) {
if (A[i] < heap[0]) {
heap[0] = A[i];
perColate(heap, 0, k);
}
}

return heap[0];

}

/**
* 建堆过程
*
* @param data
* @param len
*/
public void buildHeap(int[] data, int len) {
for (int i = (len - 1) / 2; i >= 0; i--) {
perColate(data, i, len);
}

}

/**
* 下滤操作 最大堆
*
* @param data
* @param i
* @param length
*/
public void perColate(int[] data, int i, int length) {
int len = length;
int leftChild = getLeftChild(i);
int temp = data[i];
while (leftChild < len) {
if (leftChild < (len - 1) && data[leftChild] < data[leftChild + 1]) {
leftChild++;
}
if (temp < data[leftChild]) {
data[i] = data[leftChild];
i = leftChild;
leftChild = getLeftChild(i);
} else {
break;
}

}
data[i] = temp;

}

/**
* 得到左儿子下标
*
* @param parent
* @return
*/
public int getLeftChild(int parent) {
return 2 * parent + 1;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: