最小的k个数(Java实现)

简介: 最小的k个数(Java实现)

最小的k个数(Java实现)


题目:输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。


package Day47;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Queue;
/**
 * @Author Zhongger
 * @Description 最小的k个数, 输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
 * @Date 2020.3.20
 */
public class GetLeastNumbersSolution {
    public static void main(String[] args) {
        int [] arr={4,5,1,6,2,7,3,8};
        System.out.println(Arrays.toString(new GetLeastNumbersSolution().getLeastNumbers2(arr, 4)));
    }
    /**
     * 思路就是先冒泡排序,然后取前k个数即可
     * @param arr
     * @param k
     * @return
     */
    public int[] getLeastNumbers(int[] arr, int k) {
        int[] resArr = new int[k];
        if (k<=0){
            return resArr;
        }
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j < arr.length; j++) {
                if (arr[i]>arr[j]){
                    int temp=arr[i];
                    arr[i]=arr[j];
                    arr[j]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
        for (int i = 0; i < k; i++) {
            resArr[i]=arr[i];
        }
        return resArr;
    }
}


以上的思路大家都很容易想得到,但是效率不高,时间复杂度要去到O(n^2)

所以我又学习了一种思路,借助堆这个数据结构来实现,可以使用一个大小为 k 的最大堆(大顶堆),将数组中的元素依次入堆,当堆的大小超过 k 时,便将多出的元素从堆顶弹出。由于每次从堆顶弹出的数都是堆中最大的,最小的 k 个元素一定会留在堆里。这样,把数组中的元素全部入堆之后,堆中剩下的 k 个元素就是最大的 k 个数了。

 /**
     * 最大堆法,比较直观的想法是使用堆数据结构来辅助得到最小的 k 个数。堆的性质是每次可以找出最大或最小的元素。我们可以使用一个大小为 k 的最大堆(大顶堆),
     * 将数组中的元素依次入堆,当堆的大小超过 k 时,便将多出的元素从堆顶弹出。
     * 由于每次从堆顶弹出的数都是堆中最大的,最小的 k 个元素一定会留在堆里。这样,把数组中的元素全部入堆之后,堆中剩下的 k 个元素就是最大的 k 个数了。
     * @param arr
     * @param k
     * @return
     */
    public int[] getLeastNumbers2(int[] arr, int k){
        if (k <= 0) {
            return new int[0];
        }
        //构建最大堆,因为PriorityQueue默认是最小堆的
        Queue<Integer> priorityQueue = new PriorityQueue<>(k, (i1, i2) -> Integer.compare(i2, i1));
        for (int i : arr) {
            priorityQueue.add(i);
            if (priorityQueue.size()>k){
                priorityQueue.poll();// 删除堆顶最大元素
            }
        }
        //将堆中的元素添加到数组
        int[] res=new int[priorityQueue.size()];
        int j=0;
        for (int e: priorityQueue) {
            res[j++]=e;
        }
        return res;
    }


相关文章
|
6月前
|
Java
长度最小的子数组(Java详解)
长度最小的子数组(Java详解)
76 0
|
Java
Java 实现汉字按照首字母分组排序
Java 实现汉字按照首字母分组排序
717 0
|
Java 数据安全/隐私保护
JAVA 实现上传图片添加水印(详细版)(上)
JAVA 实现上传图片添加水印(详细版)
1269 0
JAVA 实现上传图片添加水印(详细版)(上)
|
网络协议 Java
Java网络编程:UDP/TCP实现实时聊天、上传图片、下载资源等
ip地址的分类: 1、ipv4、ipv6 127.0.0.1:4个字节组成,0-255,42亿;30亿都在北美,亚洲就只有4亿 2011年就用尽了。
Java网络编程:UDP/TCP实现实时聊天、上传图片、下载资源等
剑指 Offer 45. 把数组排成最小的数 Java自定义排序
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
|
Java
Java实现拼图小游戏(7)——查看完整图片(键盘监听实例2)
由于在移动和图片中我们已经添加了键盘监听,也继承了键盘监听的接口,那么我们只需要在重写方法内输入我们的代码即可
219 0
|
存储 Java
Java实现图书管理系统
本篇文章是对目前Java专栏已有内容的一个总结练习,希望各位小主们在学习完面向对象的知识后,可以阅览本篇文章后,自己也动手实现一个这样的demo来加深总结应用已经学到知识并进行巩固。
420 0
Java实现图书管理系统
|
数据可视化 Java
Java实现拼图小游戏(1)—— JFrame的认识及界面搭建
如果要在某一个界面里面添加功能的话,都在一个类中,会显得代码难以阅读,而且修改起来也会很困难,所以我们将游戏主界面、登录界面、以及注册界面都单独编成一个类,每一个类都继承JFrame父类,并且在类中创建方法来来实现页面
540 0
Java实现拼图小游戏(1)—— JFrame的认识及界面搭建
|
数据可视化 Java 容器
Java实现拼图小游戏(7)—— 计步功能及菜单业务的实现
注意由于我们计步功能的步数要在重写方法中用到,所以不能将初始化语句写在方法体内,而是要写在成员位置。在其名字的时候也要做到“见名知意”,所以我们给它起名字为step
328 0
Java实现拼图小游戏(7)—— 计步功能及菜单业务的实现
|
Java
Java实现拼图小游戏(7)—— 作弊码和判断胜利
当我们好不容易把拼图复原了,但是一点提示也没有,完全看不出来是成功了,那么我们就需要有判断胜利的功能去弹出“成功”类的图片,以便于玩家选择是重新开始还是退出小游戏
312 0
Java实现拼图小游戏(7)—— 作弊码和判断胜利