40题目描述:

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

解析:

1.库函数,首先把数组arr排序,定义一个新的数组res,数组的长度为k
2.遍历循环数组arr,把前k个数赋值到数组res
3.最后返回数组res即可

Java:

public int[] getLeastNumbers(int[] arr, int k) {
        Arrays.sort(arr);
        int[] res = new int[k];
        for(int i = 0; i < k; i++) {
            res[i] = arr[i];
        }
        return res;
    }

JavaScript:

var getLeastNumbers = function(arr, k) {
    arr = arr.sort((a, b) => a - b);
    let res = [];
    for(let i = 0; i < k; i++) {
        res[i] = arr[i];
    }
    return res;
};

41题目描述:

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。

解析:

用大顶堆+小顶堆方法,可以看作大顶堆是普通班,小顶堆是实验班。数量上时刻保持 小顶-大顶<=1(两堆相等或者小顶比大顶多一个)。
新学生先入普通班(大顶堆),此时可能会失去平衡了,于是取大顶堆的第一个(班里最好的学生)加入实验班(小顶堆),判断若数量过多(不是等于或多一个),取第一个(实验班里最差的学生)到普通班(大顶堆)里。 取中位数的时候,若两堆数量相等,则各取堆顶取平均,若小顶比大顶多一,则多的那一个就是中位数。

Java:

class MedianFinder {
    PriorityQueue<Integer> right;
    PriorityQueue<Integer> left;
    /** initialize your data structure here. */
    public MedianFinder() {
        left = new PriorityQueue<>((n1, n2) -> n2 - n1);
        right = new PriorityQueue<>();
    }
    
    public void addNum(int num) {
        left.add(num);
        right.add(left.poll());
        if(left.size() + 1 < right.size()) {
            left.add(right.poll());
        }
    }
    
    public double findMedian() {
        if(right.size() > left.size()) {
            return right.peek();
        }
        return (double)(left.peek() + right.peek()) / 2;
    }
}

JavaScript:

var MedianFinder = function() {
    this.arr = [];
};

/** 
 * @param {number} num
 * @return {void}
 */
MedianFinder.prototype.addNum = function(num) {
    this.arr.push(num);
    this.arr.sort((a, b) => {
        return a - b;
    })
};

/**
 * @return {number}
 */
MedianFinder.prototype.findMedian = function() {
    let length = this.arr.length;
    let mid = Math.floor(length / 2);
    if(length === 0) {
        return 0;
    } else if(length % 2 === 0) {
        return (this.arr[mid - 1] + this.arr[mid]) / 2;
    } else {
        return this.arr[mid];
    }
};