Implementación de Cola Monotona y Montículo para LeetCode 239 y 347

Para el problema de la ventana deslizante máxima (LeetCode 239), el objetivo es determinar el valor máximo en cada subarray de tamaño k que se desplaza a lo largo de un array dado. Una solución eficiente utiliza una cola monotona implementada con una cola de doble extremo (deque) para mantener un seguimiento de los elementos en orden decreciente, garantizando acceso rápido al máximo actual.

La cola monotona opera insertando elementos al final, pero primero elimina todos los elementos menores que el nuevo valor para mantener la secuencia decreciente. Al eliminar elementos, solo se remueve el frente si coincide con el valor que sale de la ventana. Esto asegura que el frente de la cola siempre represente el máximo en la ventana actual.

A continuación, se presenta una implementación en C++ con nombres de variables y estructuras modificados:


class Solucion {
private:
    class ColaMonotona {
    public:
        deque<int> cola;
        void eliminar(int valor) {
            if (!cola.empty() && valor == cola.front()) {
                cola.pop_front();
            }
        }
        void insertar(int valor) {
            while (!cola.empty() && valor > cola.back()) {
                cola.pop_back();
            }
            cola.push_back(valor);
        }
        int frente() {
            return cola.front();
        }
    };
public:
    vector<int> maximoVentanaDeslizante(vector<int>& datos, int tamanoVentana) {
        ColaMonotona colaMonotona;
        vector<int> resultados;
        for (int i = 0; i < tamanoVentana; i++) {
            colaMonotona.insertar(datos[i]);
        }
        resultados.push_back(colaMonotona.frente());
        for (int i = tamanoVentana; i < datos.size(); i++) {
            colaMonotona.eliminar(datos[i - tamanoVentana]);
            colaMonotona.insertar(datos[i]);
            resultados.push_back(colaMonotona.frente());
        }
        return resultados;
    }
};
</int></int></int></int>

Para el problema de los k elementos más frecuentes (LeetCode 347), se emplea un mapa hash para contar las frecuencias de los elementos, seguido de una cola de prioridad (montículo mínimo) para seleccionar los k elementos con mayor frecuencia. El montículo se mantiene con un tamaño fijo k, asegurando que solo contenga los elementos más frecuentes al descartar los menos frecuentes durante la inserción.

La comparación personalizada en la cola de prioridad se define mediante un functor que invierte el critreio de ordenación para crear un montículo mínimo. Luego, los resultados se extraen en orden inverso para obtener la secuencia descendente de frecuencias.

Aquí está una versión en C++ con lógica reestructurada y nombres modificados:


class Solucion {
public:
    struct ComparadorFrecuencia {
        bool operator()(const pair<int int="">& a, const pair<int int="">& b) {
            return a.second > b.second;
        }
    };
    vector<int> topKFrecuentes(vector<int>& elementos, int k) {
        unordered_map<int int=""> frecuenciaMapa;
        for (int elem : elementos) {
            frecuenciaMapa[elem]++;
        }
        priority_queue<pair int="">, vector<pair int="">>, ComparadorFrecuencia> colaPrioridad;
        for (auto& par : frecuenciaMapa) {
            colaPrioridad.push(par);
            if (colaPrioridad.size() > k) {
                colaPrioridad.pop();
            }
        }
        vector<int> resultado(k);
        for (int i = k - 1; i >= 0; i--) {
            resultado[i] = colaPrioridad.top().first;
            colaPrioridad.pop();
        }
        return resultado;
    }
};
</int></pair></pair></int></int></int></int></int>

Estas soluciones demuestran el uso de estructuras de datos especializadas, como colas de doble extremo y montículos, para resolver problemas de algoritmos de manera eficiente en C++.

Etiquetas: leetcode cola-monotona montículo-mínimo mapa-hash algoritmos

Publicado el 7-7 22:16