最小的k个数

题目描述

 

 

此题和最大乘积有着相似的解法:https://www.cnblogs.com/cstdio1/p/11041901.html

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> arr, int k) {
        vector<int> mini; 
        if(arr.size()<k) return mini;
        for(int i = 0; i < k; i++){
        for(int j = i + 1; j <arr.size() ; j++) if(arr[j] < arr[i]) swap(arr[j], arr[i]);
        mini.push_back(arr[i]);
    } return mini;   
    }
};

 题解:主要利用冒泡排序思想,因为只需要最小的k个数,所以只需要比较k趟就可以了

class Solution {
    public int[] getLeastNumbers(int[] arr, int k) {
    int len=arr.length;
    for(int i=0;i<k;i++){
        for(int j=0;j<len-1-i;j++){
            if(arr[j]<arr[j+1]){
                int t=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=t;
            }
        }
    }
    return Arrays.copyOfRange(arr,len-k,len);
    }
}

 

利用java自带的堆, 这里我们采用大根堆。

 

// 保持堆的大小为K,然后遍历数组中的数字,遍历的时候做如下判断:
// 1. 若目前堆的大小小于K,将当前数字放入堆中。
// 2. 否则判断当前数字与大根堆堆顶元素的大小关系,如果当前数字比大根堆堆顶还大,这个数就直接跳过;
//    反之如果当前数字比大根堆堆顶小,先poll掉堆顶,再将该数字放入堆中。
class Solution {
    public int[] getLeastNumbers(int[] arr, int k) {
        if (k == 0 || arr.length == 0) {
            return new int[0];
        }
        // 默认是小根堆,实现大根堆需要重写一下比较器。
        Queue<Integer> pq = new PriorityQueue<>((v1, v2) -> v2 - v1);
        for (int num: arr) {
            if (pq.size() < k) {
                pq.offer(num);
            } else if (num < pq.peek()) {
                pq.poll();
                pq.offer(num);
            }
        }
        
        // 返回堆中的元素
        int[] res = new int[pq.size()];
        int idx = 0;
        for(int num: pq) {
            res[idx++] = num;
        }
        return res;
    }
}

 

posted @ 2019-07-24 11:56  浅滩浅  阅读(148)  评论(0)    收藏  举报