(两百三十五)leetcode 数据流中的第K大元素

1.题目

设计一个找到数据流中第K大元素的类(class)。注意是排序后的第K大元素,不是第K个不同的元素。

你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包含数据流中的初始元素。每次调用 KthLargest.add,返回当前数据流中第K大的元素。

示例:

int k = 3;
int[] arr = [4,5,8,2];
KthLargest kthLargest = new KthLargest(3, arr);
kthLargest.add(3);   // returns 4
kthLargest.add(5);   // returns 5
kthLargest.add(10);  // returns 5
kthLargest.add(9);   // returns 8
kthLargest.add(4);   // returns 8
说明: 
你可以假设 nums 的长度≥ k-1 且k ≥ 1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-a-stream
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

 

2.思路

完全没有思路,之后补了下堆的基础,堆是完全二叉树,分最大堆和最小堆,顾名思义,最大堆就是最大值在上面,最小堆相反,数据存储总是从上到下,从左到右,并且每个小树杈也符合最大堆或者最小堆的定义

所以这题其实是先构造出容量为k的最小堆,然后后来的元素比最小堆的最小值小则忽略,否则替换最小值,进行下沉操作,获得最新的最小值,返回。

 

3.coding

class KthLargest {

    /**小顶堆*/
    private int[] minHeap;
    /**堆的规模*/
    private final int k;
    /**堆的最后一个元素的索引*/
    private int last = -1;
    //你可以假设 nums 的长度≥ k-1 且k ≥ 1。
    public KthLargest(int k, int[] nums) {
        this.k  = k;
        minHeap = new int[k];
        for(int i = 0; i < k && i < nums.length; i++) {
            minHeap[i] = nums[i];
            last = i;
        }

        if(last == k -1) {
            order();
            for (int i = k; i < nums.length; i++){
                add(nums[i]);
            }
        }



    }

    public int add(int val) {
        if (last != k -1){
            minHeap[k-1] = val;
            last = k -1;
            order();
        } else if (val > minHeap[0]){
            minHeap[0] = val;
            sink(0);
        }
        return minHeap[0];
    }

    /**堆的有序化*/
    private void order() {
        for(int i = last/2; i >=0; i--){
            sink(i);
        }
    }

    /**下沉*/
    private void sink(int i) {
        while (2*i+1 <= k-1 ) {
            int left = 2 * i + 1;
            int right = 2 * i + 2;

            int minIdex;
            if(right <= k-1 && minHeap[left] > minHeap[right]){
                minIdex = right;
            } else {
                minIdex = left;
            }

            if(minHeap[minIdex] < minHeap[i]) {
                swap(i, minIdex);
                i = minIdex;
            } else {
                break;
            }
        }

    }

    private void swap(int i, int minIdex) {
        int temp = minHeap[i];
        minHeap[i] = minHeap[minIdex];
        minHeap[minIdex] = temp;
    }
}

 

 

 

相关推荐
©️2020 CSDN 皮肤主题: 鲸 设计师:meimeiellie 返回首页