[Leetcode] 703. El K-ésimo elemento más grande en el flujo de datos (k-ésimo-elemento-más grande-en-un-flujo) (simulación) [simple]

Enlace

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

pérdida de tiempo

Resolución de problemas: 1 h 25 min
Resolución de problemas: 26 min

Título

Diseñe una clase que encuentre el k-ésimo elemento más grande en el flujo de datos. Tenga en cuenta que es el k-ésimo elemento más grande después de la clasificación, no el k-ésimo elemento diferente.

Implemente la clase KthLargest:

  • KthLargest (int k, int [] nums) inicializa el objeto usando números enteros k y números enteros de flujo.
  • int add (int val) Después de insertar val en el flujo de datos nums, devuelve el k-ésimo elemento más grande en el flujo de datos actual.

Ideas

Para establecer (el orden descendente) antes de los elementos principales de k la parte superior de la pila pequeña, es decir, la parte superior de la pila de modo que los elementos principales sean k, agregue cada flujo de datos de actualización, si es val <= 堆顶元素necesario, porque antes de la adición de k -th elemento más grande no cambiará val ninguno de los elementos principales del k-ésimo elemento o la parte superior de la pila; y si el val > 堆顶元素primero está obligado a cambiar el val k-unir elementos principales, los elementos de la parte superior actual de la pila ya no es útil, se convierte en un k + 1 o elemento grande, de modo que el valor del elemento superior de la pila se cambia directamente a val, y la pila superior pequeña se ajusta para que la parte superior de la pila se convierta en k -th elemento más grande de nuevo.

Complejidad de tiempo: O (max (addnum ∗ logk, nlogn)) O (max (addnum * logk, nlogn))O ( m a x ( a d d n u ml o g k ,n l o g n ) )

Código AC

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);
 */

Supongo que te gusta

Origin blog.csdn.net/Krone_/article/details/113788896
Recomendado
Clasificación