返回

算法伴我夜深人静展风华,路飞来了玩几个算法助兴

前端

12点,算法伴我夜深人静展风华,一个人枯坐一角刷编程题,也是寂寞,却也是充实。对于每个充满想象的算法写手来说,夜深人静的时候,代码伴着算法,闪烁的字符将脑海中的灵感幻化成实际,赋予程序以生命力。路飞就为大家准备几个算法,大家一起在夜深人静之时,一起来嗨起来!

1. 问题引入

小易是位算法爱好者,为了考入谷歌,他每天都在LeetCode上刷题。今天他又发现一道好题,他想尽快搞定,以便欣赏一下阳台上的明月。

他需要实现这样一个算法:

在数据流中,每秒收到一个整数,需要处理这样一个问题:给你一个整数数组dataStream和一个整数k,从中找到第k大的元素。

算法被抽象成如下:

class KthLargest {
    private int k;
    private PriorityQueue<Integer> pq;

    public KthLargest(int k, int[] nums) {
        this.k = k;
        this.pq = new PriorityQueue<>(Collections.reverseOrder());
        for (int num : nums) {
            add(num);
        }
    }

    public int add(int val) {
        pq.offer(val);
        if (pq.size() > k) {
            pq.poll();
        }
        return pq.peek();
    }
}

很容易想到,按照题意,我们需要记录当前流中的k个最大的数,这些数构成一个大小为k的数组,此数组中的元素始终是流中已出现的最大的k个数字。因此,很容易想到使用一个大小为k的优先队列来存储这些数,每次新来一个数,将其加入到优先队列中,如果队列的长度大于k,则将队列中最小的数poll掉。这样,队列中的k个数始终是当前流中最大的k个数。

1)按照最大K元素很容易想到排序

int kthLargest = dataStream[0];
Arrays.sort(dataStream);
for(int i=dataStream.length-k;i<dataStream.length;i++){
    kthLargest = dataStream[i];
}
return kthLargest;

2)将add的数据添加到数组,在添加过程中,通过查找方法将val数值放到数组对应位置,使添加完数据的数组依然是有序的。

int[] arr = new int[k];
for(int i=0;i<arr.length;i++){
    arr[i] = Integer.MAX_VALUE;
}
int index = 0;
for(int i=0;i<dataStream.length;i++){
    index = binarySearch(arr,val);
    for(int j=arr.length-1;j>index;j--){
        arr[j] = arr[j-1];
    }
    arr[index] = val;
}
return arr[k-1];

3)输出第K个元

int index = 0;
for(int i=0;i<dataStream.length;i++){
    index = binarySearch(arr,val);
    for(int j=arr.length-1;j>index;j--){
        arr[j] = arr[j-1];
    }
    arr[index] = val;
}
return arr[k-1];

2. 结语

以上就是夜深人静时,在算法伴随下绽放的代码之美。它如一杯醇香的热茶,能让人平静下来,凝神思考,并在灵感中获得一整天编程的动力。