最小的k个数
关于堆排序,堆的下沉操作,圆满解决。
题目
输入n个整数,找出其中最小的k个数。例如输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
思路
思路一:同剑指offer(39) 数组中出现次数超过一半的数字中使用partition()方法,基于数组的第k个数字调整,使得更小的k个数字都在数组左边即可。
思路二:依次遍历n个整数,用一个容器存放最小的k个数字,每遇到比容器中最大的数字还小的数字时,将最大值替换为该数字。容器可以使用最大堆或者红黑树来实现。本文根据堆排序的原理来实现。
测试用例
功能测试(数组中存在/不存在重复数字)
边界值测试(k=1或者等于数组长度)
特殊测试(null、k<1、k大于数组长度)
java代码
用partition函数修改数组
1 | /** |
基于堆的容器
1 | /** |
总结
本题就是对快速排序和堆排序的延伸。
k小于等于0的情况别忘记了
方法二,只需要在原始数组中进行读入操作,而所有的写操作和判断都是在容器中进行的,不用反复读取原始数组,思想非常好。
记得要弄清楚是否可以改变原始输入的数组。
partition函数:即是快速排序的基础,也可以用来查找n个数中第k大的数字。
当涉及到频繁查找和替换最大最小值时,二叉树是非常合适的数据结构,要能想到堆和二叉树。