[Leetcode] 703. O K-ésimo maior elemento no fluxo de dados (k-ésimo elemento-em-um-stream) (simulação) [simples]

link

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

demorado

Resolução de problemas: 1 h 25 min
Resolução de problemas: 26 min

Título

Projete uma classe que encontre o k-ésimo maior elemento no fluxo de dados. Observe que é o k-ésimo maior elemento após a classificação, não o k-ésimo elemento diferente.

Implemente a classe KthLargest:

  • KthLargest (int k, int [] nums) inicializa o objeto usando números inteiros k e números inteiros de fluxo.
  • int add (int val) Depois de inserir val no fluxo de dados nums, retorne o k-ésimo maior elemento no fluxo de dados atual.

Ideias

Para estabelecer (a ordem decrescente) antes dos elementos principais do topo da pilha pequena k, ou seja, topo da pilha de modo que os elementos principais sejam k, adicione cada fluxo de dados de atualização, se for val <= 堆顶元素necessário lidar com, porque antes da adição do k -ésimo maior elemento não mudará val qualquer um dos elementos principais do k-ésimo elemento ou topo da pilha; e se o val > 堆顶元素primeiro for obrigado a alterar os elementos principais val k-join, os elementos do topo atual da pilha não é mais útil, torna-se um grande k + 1 o elemento, de modo que o valor do elemento de topo da pilha é diretamente alterado para val, e a pequena pilha de topo é ajustada de modo que o topo da pilha se torna k -º maior elemento novamente.

Complexidade de tempo: 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);
 */

Acho que você gosta

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