无序数组中最小的k个数

对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的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;
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值