2012-04-14 3 views
2

Je tente d'écrire un algorithme pour renvoyer true si un élément majoritaire existe dans un tableau et false dans le cas contraire. edit: je ne peux dire que si deux éléments sont égaux. ce qui signifie que je ne peux pas utiliser < ou>, only =. edit: la solution devrait être dans une méthode de division et de conquête. son exécution sur nlogn aller shouldnt, et je l'ai écrit quelque chose en java, mais je ne suis pas sûr si elle est correcte et comment calculer le temps d'exécution .. voici ce que je suis:Algorithmes | élément majoritaire

public static boolean MajorityBoolean(int[] arr) { 
    int c; 
    int n = arr.length; 
    for (int i = 0; i < n; i = i + 2) { 
     System.out.println("*"); 
     if ((arr[i] == arr[(i + 1)%n]) || ((arr[i] == arr[(i - 1+n)%n]))) { 
      c = 0; 
      for (int j = 0; j < n; j = j + 1) 
       if (arr[j] == arr[i]) 
        c = c + 1; 
      if (c > n/2) 
       return true; 
     } 
    } 
    return false; 
} 
+0

(n) I a ajouté une étiquette de devoirs, puisque cela semble être le cas. Si je me trompe, corrigez-moi s'il vous plaît. – amit

+0

duplication possible de [Rechercher l'élément majoritaire dans le tableau] (http://stackoverflow.com/questions/4325200/find-majority-element-in-array) – erickson

+0

Plus précisément, [this] (http://stackoverflow.com/a/9487018/3474) est la meilleure solution à la question en double. – erickson

Répondre

5

L'exécution de l'algorithme décrit est O(n^2). La boucle externe est exécutée n/2 fois, ainsi le compteur interne j est réinitialisé n/2 fois, et ainsi la boucle interne est exécutée au total de O(n^2) fois.

Je ne suis pas sûr que je suis la logique derrière votre idée, mais voici deux approches comment je mettre en œuvre [en pseudo-code de haut niveau]:

(1) créer un histogram de la données:

  • créer un Map<Integer,Integer> [la clé est l'élément et la valeur est le nombre de occurances]
  • itérer le tableau, et pour chaque élément compte combien de fois il semble
  • itérer l'histogramme et trouver s'il y a un maximum unique.
  • S'il existe - retour vrai, sinon retour faux.

Cette approche est moyenne de O(n) si vous utilisez un HashMap comme carte.

(2) de tri et de trouver Max occurances:

  • trier le tableau - à la suite, tous les éléments sont égaux à côté de l'autre. Vous pouvez utiliser Arrays.sort(array) pour le tri.
  • Comptez le nombre de fois que chaque élément apparaît [similaire à l'idée de l'histogramme], et déterminez s'il existe un maximum unique. Vous n'avez pas besoin de maintenir les données pour tous les éléments, il suffit de maintenir pour le top 2, et à la fin pour voir si elles sont identiques.

Cette solution est O(nlogn) moyenne + pire des cas [en fait, selon le genre - merge sor vous donne t O(nlogn) pire des cas, alors que quick-sort vous donne O(n^2) pire des cas, et les deux sont O(nlogn) le cas moyen].

EDIT:

j'ai mal compris le problème à portée de main, je pensais que vous cherchez s'il y a un maximum unique. Ces 2 solutions conviennent toujours au problème, il suffit de modifier la dernière étape de chaque [pour vérifier si l'élément le plus courant apparaît plus de la moitié des fois, ce qui est encore assez facile et faisable dans O(n)].

De plus, il existe une autre solution: Utilisez selection algorithm pour trouver la médiane, et après l'avoir trouvé, vérifiez s'il s'agit d'un élément majoritaire et revenez si c'est le cas. Puisque l'algorithme de sélection est une solution basée sur la division et la conquête, je pense que cela correspond à vos besoins.

+0

d'abord, merci pour votre aide! deuxièmement, mon idée était que dans chaque tableau qui a un élément majoritaire, il doit y avoir deux nombres identiques les uns après les autres (en considérant que le tableau est une sorte de cercle, de sorte que le dernier élément est proche du premier). est-ce une bonne idée? btw, apparemment je devais écrire l'algorithme dans une méthode divide-n-conquer, donc le mien n'est pas bon (aussi son exécution est O (n²) qui est plus que) (nlogn)). – shachar0n

+0

@ shachar0n: (1) Je ne suis toujours pas la logique, pourquoi le tableau est-il circulaire? : \. (2) J'ai mal compris la question, je pensais que vous cherchiez s'il y a un maximum unique. Ces deux solutions répondent toujours au problème, avec une modification sommaire dans la dernière étape de chaque solution. (3) La question que vous décrivez peut être résolue en utilisant [algorithme de sélection] (http://en.wikipedia.org/wiki/Selection_algorithm). Trouvez la médiane - puis regardez si c'est l'élément majoritaire. L'algorithme de sélection est en fait une solution de devide et de conquête. – amit

+0

(1) ce qui était le cas si un tableau a un élément majoritaire, c'est qu'il doit avoir deux éléments proches qui sont identiques. si le tableau est comme ceci: 1010101, alors les derniers et premiers éléments sont les mêmes - et c'est ce que je veux dire en traitant le tableau comme un cercle (en utilisant modulu%). (2) (3) j'ai oublié de mentionner une autre restriction: je ne peux savoir si deux éléments sont identiques mais je ne peux pas dire si l'un est plus grand ou plus petit que l'autre, ce qui signifie que je ne peux utiliser que :><. – shachar0n

0

Voici un O solution Find Majority Element

+0

Ceci indique une bonne solution, mais vous devriez voter pour fermer les questions en double si vous le pouvez, ou simplement faire un commentaire sur la question si vous ne le pouvez pas. – erickson

1

Un élément majoritaire dans une matrice A [] de taille n est un élément qui apparaît plus de n/2 fois

public static boolean find(int[] arr, int size) { 
int count = 0, i, mElement; 
for (i = 0; i < size; i++) { 
    if (count == 0) 
     mElement = arr[i]; 
    if (arr[i] == mElement) 
     count++; 
    else 
     count--; 
} 
count = 0; 
for (i = 0; i < size; i++) 
    if (arr[i] == mElement) 
     count++; 
if (count > size/2) 
    return true; 
return false; 
}