剑指offer 最小的k个数

寻找最小的K个数
本文介绍两种高效算法,用于从一组整数中找到最小的K个数。一种基于快速排序,时间复杂度O(n),通过调整数组使前K个元素为最小;另一种使用最大堆,时间复杂度O(nlgk),适用于实时数据流处理。

题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

 

解法一:根据快速排序,基于数组的第k个数字来调整,使得k左边的数字都小于k,k右边的数字都大于k。

调整后,左边的k个数字就是最小的k个数字,时间复杂度O(n)。

/**
 * @author yuan
 * @date 2019/2/19
 * @description 基于partition,时间复杂度O(n)
 */
public class 最小的K个数 {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> result = new ArrayList<>(input.length);
        if (k < 1 || k > input.length) {
            return result;
        }
        int l = 0, r = input.length - 1;
        int index = partition(input, l, r);
        while (index != k - 1) {
            if (index > k - 1) {
                r = index - 1;
                index = partition(input, l, r);
            } else {
                l = index + 1;
                index = partition(input, l, r);
            }
        }
        for (int i = 0; i < k; i++) {
            result.add(input[i]);
        }
        return result;
    }

    /**
     * 切片
     * @param a
     * @param left
     * @param right
     * @return
     */
    private int partition(int[] a, int left, int right) {
        int i = left, j = right;
        int base = a[left];
        while (i < j) {
            while (i < j && a[j] >= base) {
                --j;
            }
            while (i < j && a[i] <= base) {
                ++i;
            }
            swap(a, i, j);
        }
        swap(a, left, i);
        return i;
    }

    private void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

 

解法二:用最大堆,时间复杂度O(nlgk)

先创建一个大小为k的堆,接下来每次读取一个整数,当堆的数字小于k,直接放入堆中。

若堆已经有k个数字,将堆中最大的值和当前整数比较,如果当前整数小于堆的最大值,则将堆中的最大值替换为当前整数。

如果当前整数比堆的最大值大,则不可能是最小的k个整数之一,直接抛弃。


/**
 * @author yuan
 * @date 2019/2/19
 * @description 最大堆,时间复杂度O(nlgk)
 * 用最大堆保存这k个数,每次只和堆顶比,如果比堆顶(堆中最大的元素)小,删除堆顶,新数入堆。
 * 否则抛弃
 */
public class 最小的K个数 {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> result = new ArrayList<>(input.length);
        int len = input.length;
        if (k > len || k < 1) {
            return result;
        }
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, Comparator.reverseOrder());
        for (int i = 0; i < len; i++) {
            if (maxHeap.size() < k) {
                maxHeap.offer(input[i]);
            } else if (input[i] < maxHeap.peek()) {
                // 如果当前整数比堆中最大的元素还小,用这个整数替换已有的最大值
                maxHeap.poll();
                maxHeap.offer(input[i]);
            }
        }
        result.addAll(maxHeap);
        return result;
    }
}

 

MATLAB代码实现了一个基于多种智能优化算法优化RBF神经网络的回归预测模型,其核心是通过智能优化算法自动寻找最优的RBF扩展参数(spread),以提升预测精度。 1.主要功能 多算法优化RBF网络:使用多种智能优化算法优化RBF神经网络的核心参数spread。 回归预测:对输入特征进行回归预测,适用于连续值输出问题。 性能对比:对比不同优化算法在训练集和测试集上的预测性能,绘制适应度曲线、预测对比图、误差指标柱状图等。 2.算法步骤 数据准备:导入数据,随机打乱,划分训练集和测试集(默认7:3)。 数据归一化:使用mapminmax将输入和输出归一化到[0,1]区间。 标准RBF建模:使用固定spread=100建立基准RBF模型。 智能优化循环: 调用优化算法(从指定文件夹中读取算法文件)优化spread参数。 使用优化后的spread重新训练RBF网络。 评估预测结果,保存性能指标。 结果可视化: 绘制适应度曲线、训练集/测试集预测对比图。 绘制误差指标(MAE、RMSE、MAPE、MBE)柱状图。 十种智能优化算法分别是: GWO:灰狼算法 HBA:蜜獾算法 IAO:改进天鹰优化算法,改进①:Tent混沌映射种群初始化,改进②:自适应权重 MFO:飞蛾扑火算法 MPA:海洋捕食者算法 NGO:北方苍鹰算法 OOA:鱼鹰优化算法 RTH:红尾鹰算法 WOA:鲸鱼算法 ZOA:斑马算法
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值