Détection du nombre majoritaire dans une matrice

Description du problème

Dans une matrice de dimensions n × m, un nombre apparaît plus de la moitié des fois. Concevez un algorithme efficace pour identifier ce nombre.

Format d'entrée : La première ligne contient deux entiers n et m représentant la taille de la matrice (1≤n,m≤10^3). Les n lignes suivantes contiennent chacune m entiers positifs correspondant aux éléments de la matrice.

Format de sortie : Afficher un entier, le nombre qui apparaît plus de la moitié des fois dans la matrice.

Exemple d'entrée :
3 3
1 2 3
2 2 2
1 2 2

Exemple de sortie :
2

Solution 1 : Utliisation de l'algorithme de vote de Boyer-Moore

Analyse

Cette approche adapte l'algorithme de vote de Boyer-Moore pour trouver un candidat potentiel, puis vérifie s'il représente effectivement la majorité.

Code clé

La méthode detecterElementMajoritaire prend une matrice 2D, la transforme en tableau linéaire, identifie un candidat et le valide.

private static int detecterElementMajoritaire(int[][] matrice) {
    if (matrice == null || matrice.length == 0 || matrice[0].length == 0) {
        return -1;
    }
    int[] tableauLineaire = aplatirMatrice(matrice);
    int candidat = trouverCandidat(tableauLineaire);
    return verifierMajorite(candidat, tableauLineaire) ? candidat : -1;
}

Méthode aplatirMatrice : Convertit la matrice 2D en un tableau 1D.

private static int[] aplatirMatrice(int[][] matrice) {
    int lignes = matrice.length;
    int colonnes = matrice[0].length;
    int[] tableau = new int[lignes * colonnes];
    int index = 0;
    for (int i = 0; i < lignes; i++) {
        for (int j = 0; j < colonnes; j++) {
            tableau[index++] = matrice[i][j];
        }
    }
    return tableau;
}

Méthode trouverCandidat : Implémente l'algorithme de vote pour déterminer un candidat. Parcourt le tableau, en maintenatn un compteur pour le candidat actuel. Si le compteur tombe à zéro, un nouveau candidat est sélectionné.

private static int trouverCandidat(int[] donnees) {
    int compteur = 0;
    int potentiel = -1;
    for (int valeur : donnees) {
        if (compteur == 0) {
            potentiel = valeur;
        }
        compteur += (valeur == potentiel) ? 1 : -1;
    }
    return potentiel;
}

Méthode verifierMajorite : Vérifie si le candidat apparaît plus de la moitié des fois dans le tableau.

private static boolean verifierMajorite(int candidat, int[] donnees) {
    int occurrences = 0;
    for (int valeur : donnees) {
        if (valeur == candidat) {
            occurrences++;
        }
    }
    return occurrences > donnees.length / 2;
}

Complexité temporelle

La conversion en tableau linéaire prend O(nm). La recherche du candidat parcourt le tableau, soit O(nm). La vérification nécessite également O(nm). La compelxité totale est donc O(3nm).

Solution 2 : Utilisation d'une table de hachage

Analyse

Cette méthode optimisée emploie une table de hachage pour compter les occurrences de chaque nombre et identifier directement celui qui dépasse la moitié.

Code clé

Création d'une table de hachage pour stocker les comptes et recherche du nombre majoritaire.

Map<Integer, Integer> compteur = new HashMap<>();
for (int i = 0; i < n * m; i++) {
    int element = scanner.nextInt();
    compteur.put(element, compteur.getOrDefault(element, 0) + 1);
}

for (Map.Entry<Integer, Integer> entree : compteur.entrySet()) {
    if (entree.getValue() * 2 > n * m) {
        System.out.println(entree.getKey());
    }
}

Complexité temporelle

La lecture des éléments et la mise à jour de la table de hachage s'effectuent en O(nm). L'itération sur les entrées de la table est également O(nm). La complexité globale est O(nm).

Étiquettes: Boyer-Moore Voting Algorithm Hash Map Matrice Algorithme d'optimisation Java

Publié le 8 juin à 09h18