[Leetcode] 703. The Kth largest element in the data stream (kth-largest-element-in-a-stream) (simulation) [simple]

link

https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/

time consuming

Problem solving: 1 h 25 min
Problem solving: 26 min

Title

Design a class that finds the k-th largest element in the data stream. Note that it is the k-th largest element after sorting, not the k-th different element.

Please implement the KthLargest class:

  • KthLargest(int k, int[] nums) initializes the object using integer k and integer stream nums.
  • int add(int val) After inserting val into the data stream nums, return the k-th largest element in the current data stream.

Ideas

To establish (the descending order) before the major elements of k small pile top, i.e., top of the stack so that major elements are k, add each update data streams, if val <= 堆顶元素the need to deal with, because prior to addition of the k-th largest element will not change val any one of major elements of the k-th element or top of the stack; and if the val > 堆顶元素former is bound to change the val k-join major elements, the elements of the current top of the stack is no longer useful, it becomes a large k + 1 th element, so that the The value of the top element of the pile is directly changed to val, and the small top pile is adjusted so that the top of the pile becomes the k-th largest element again.

Time complexity: O (max (addnum ∗ logk, nlogn)) O(max(addnum*logk, nlogn))O(max(addnuml o g k ,n l o g n ) )

AC code

class KthLargest {
    
    
private:
    vector<int> arr;
    int k;
public:
    // 小顶堆
    void heapAdjust(vector<int>& arr, int l, int r) {
    
     // 只有堆顶位置不对,调整他
        int dad = l;
        int son = dad * 2 + 1;
        while (son <= r) {
    
     // 若子節點指標在範圍內才做比較
            if (son + 1 <= r && arr[son] > arr[son + 1]) // 先比較兩個子節點大小,選擇最小的
                son++;
            if (arr[dad] < arr[son]) // 如果父節點小於子節點代表調整完畢,直接跳出函數
                return;
            else {
    
     // 否則交換父子內容再繼續子節點和孫節點比較
                swap(arr[dad], arr[son]);
                dad = son;
                son = dad * 2 + 1;
            }
        }
    }
    
    KthLargest(int k, vector<int>& nums) {
    
    
        this->arr = nums;
        sort(arr.begin(), arr.end(), greater<int>());
        this->k = k;
        if(arr.size() >= k) {
    
    
            for (int i = k/2-1; i >= 0; --i) {
    
     // 从第一个非叶子结点开始 
                heapAdjust(arr, i, k-1);
            }
        }
    }
    
    int add(int val) {
    
    
        if(arr.size() < k) {
    
    
            arr.push_back(val);
            for (int i = k/2-1; i >= 0; --i) {
    
     // 从第一个非叶子结点开始 
                heapAdjust(arr, i, k-1);
            }
        }
        else {
    
    
            if(val > arr[0]) {
    
    
                arr[0] = val;
                heapAdjust(arr, 0, k-1);
            }
        }
        return arr[0];
    }
};

/**
 * Your KthLargest object will be instantiated and called as such:
 * KthLargest* obj = new KthLargest(k, nums);
 * int param_1 = obj->add(val);
 */

Guess you like

Origin blog.csdn.net/Krone_/article/details/113788896