Trouver les k éléments les plus fréquents

L'objectif est d'identifier les k éléments qui apparaissent le plus souvent dans un tableau donné. L'algorithme doit être plus performant qu'une complexité temporelle de O(n log n).

Analyse du problème :

  1. Compter la fréquence de chaque élément.
  2. Trier les éléments en fonctino de leur fréquence.
  3. Sélectionner les k éléments les plus fréquents.

La clé réside dans l'implémentation efficace de la partie tri et sélection pour respecter la contrainte de complexité temporelle.

Utilisation d'une file de priorité (Tas Min) :

Une file de priorité est une structure de données adoptée pour gérer des éléments avec des priorités et en extraire le plus (ou le moins) prioritaire. Dans ce cas, nous utiliserons un tas min (min-heap) pour conserver les k éléments les plus fréquents rencontrés jusqu'à présent. Si la taille du tas dépasse k, l'élément avec la fréquence la plus basse (le sommet du tas min) est retiré.

Implémentation du comparateur pour le tas min :

Par défaut, std::priority_queue en C++ implémente un tas max. Pour obtenir un tas min basé sur la fréquence (le deuxième élément de la paire), nous devons fournir un comparateur personnalisé.


struct CompareFrequency {
    bool operator()(const std::pair& lhs, const std::pair& rhs) const {
        // Comparaison pour un tas min : lhs.second doit être supérieur à rhs.second
        // pour que lhs soit considéré comme "moins prioritaire".
        return lhs.second > rhs.second;
    }
};

Code C++ :


#include <vector>
#include <unordered_map>
#include <queue>
#include <utility> // Pour std::pair

class Solution {
public:
    // Comparateur personnalisé pour un tas min basé sur la fréquence.
    struct CompareFrequency {
        bool operator()(const std::pair& lhs, const std::pair& rhs) const {
            return lhs.second > rhs.second;
        }
    };

    std::vector<int> topKFrequent(std::vector<int>& nums, int k) {
        // 1. Compter la fréquence de chaque élément.
        std::unordered_map<int int=""> frequencyMap;
        for (int num : nums) {
            frequencyMap[num]++;
        }

        // 2. Utiliser un tas min pour garder les k éléments les plus fréquents.
        // La paire stocke {élément, fréquence}.
        std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int>>, CompareFrequency> minHeap;

        for (const auto& pair : frequencyMap) {
            minHeap.push(pair);
            // Si la taille du tas dépasse k, retire l'élément le moins fréquent.
            if (minHeap.size() > k) {
                minHeap.pop();
            }
        }

        // 3. Extraire les k éléments du tas.
        std::vector<int> result;
        result.reserve(k); // Pré-allouer la mémoire pour k éléments.
        while (!minHeap.empty()) {
            result.push_back(minHeap.top().first);
            minHeap.pop();
        }

        // Le tas min contient les k éléments les plus fréquents.
        // L'ordre dans 'result' peut être arbitraire, ce qui est acceptable selon l'énoncé.
        // Si un ordre spécifique est requis (par exemple, décroissant de fréquence),
        // une inversion ou une autre approche de tri serait nécessaire après l'extraction.
        
        return result;
    }
};
</int></int></int></int>

Étiquettes: C++ unordered_map priority_queue tas min Algorithme

Publié le 4 juillet à 01h06