求N个数中最小的K的数 O(NlogK)

本文介绍了一种使用最大堆实现的算法,用于找出数组中最小的k个整数。该算法首先创建一个大小为k的最大堆,然后通过遍历输入数组并比较堆顶元素来维护这个最大堆,确保堆内始终保存最小的k个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.util.ArrayList;

public class HeapSorted {
    public static void main(String[] rags) {
        HeapSorted testSorted = new HeapSorted();
        int[] input = {2,2,7,4,8,2,9,3,6,5};
        int k = 4;
        System.out.println(testSorted.GetLeastNumbers_Solution(input, k));
    }

    public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        if (input == null || input.length == 0 || input.length < k) {
            return res;
        }
        if (k == 0)
            return res;
        int[] maxHeap = new int[k];
        //初始化堆
        for (int i = 0; i < maxHeap.length; i++) {
            maxHeap[i] = input[i];
        }
        //将初始化的堆调整为最大堆。最大堆:根节点的值总是大于子树中任意节点的值
        // 注意是--i,从下往上
        for (int i = (maxHeap.length - 1) / 2; i >= 0; i--) {
            adjustHeap(maxHeap, i);
        }
        //遍历初始数组不断调整最大堆
        for (int i = k; i < input.length; i++) {
            if (maxHeap[0] > input[i]) {
                maxHeap[0] = input[i];
                adjustHeap(maxHeap, 0);   // 0位置,即根节点的值为最大值
            }
        }
        for (int i = 0; i < maxHeap.length; i++) {
            res.add(maxHeap[i]);
        }
        return res;
    }

    static void adjustHeap(int maxHeap[], int i) {
        int index = i;
        int lchild = 2 * i + 1;  //i的左孩子节点序号
        int rchild = 2 * i + 2; //i的右孩子节点序号
        if (index <= (maxHeap.length - 1) / 2) {
            //寻找子节点中最大的节点
            if (lchild < maxHeap.length && maxHeap[index] < maxHeap[lchild]) { //左孩子大于index
                index = lchild;
            }
            if (rchild < maxHeap.length && maxHeap[index] < maxHeap[rchild]) { //右孩子大于index
                index = rchild; //此时index为左右孩子中较大的那个
            }

            if (i != index) {
                //将节点与最大的子节点交换
                int tmp = maxHeap[index];
                maxHeap[index] = maxHeap[i];
                maxHeap[i] = tmp;
                //交换后,子树可能不满足最大推,递归调整。
                adjustHeap(maxHeap, index); //因为交换下来一个小的数字,要调整的是被交换的子树
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值