Le plus commun élément dans un tableau / Trouver de la majorité relative, de façon déterministe en temps O(n) en temps et O(1) de l'espace?
Ainsi, par exemple, la réponse au tableau:
1, 11, 3, 95, 23, 8, 1
serait de 1, puisque tous les autres éléments qu'une seule fois alors que 1 se produit deux fois.
Beaucoup de questions similaires à cette question que j'ai vu sur stackoverflow demander de trouver la majorité absolue (la réponse se produit au moins n/2 dans un tableau de longueur n), ou de répondre à la question à l'aide de tri ou d'une table de hachage. L'ancien n'est pas ce que je demande, et le dernier est trop faible ( O(n log n) pour le tri ) ou s'il utilise trop de mémoire ( O(n) pour une table de hachage ).
Fait un tel algorithme n'existe pas? Si non, est-il un élément de preuve indiquant pourquoi c'est impossible? Y compris une source, ce serait bien.
Est-ce devoirs?
Pouvez-vous expliquer ce que vous entendez par une analyse linéaire et non, ce n'est pas de devoirs
double possible de Comment pouvons-nous trouver un certain nombre dans la gamme en O(n) en temps et O(1) de la complexité de l'espace
Si votre tableau contient des entiers, alors vous pouvez le faire en O(n) en temps et O(1) de l'espace. Trier le tableau à l'aide d'une binaire de tri radix. Ensuite, faire une passe à travers le tableau pour déterminer le plus commun élément. Radix de tri nécessite 32 traverse tableau 33 passe au total, ce qui est une constante, de sorte que O(n).
OriginalL'auteur weeb | 2012-08-02
Vous devez vous connecter pour publier un commentaire.
Utiliser l'idée de partir d'ici:
Comment pouvons-nous trouver un certain nombre dans la gamme en O(n) en temps et O(1) de la complexité de l'espace
Et d'appliquer une technique similaire à comptage de tri. C'est, de créer des N bacs (un tableau de taille N), où N est le plus grand entier vous attend. C'est toujours en O(1) de l'espace. Ensuite, parcourir le tableau d'origine en O(n) le temps, et lorsque vous rencontrez une valeur je, incrément de vos résultats tableau à l'indice je par 1. Ensuite, parcourir les résultats de tableau (nouveau O(1) temps), trouver la plus grande valeur. L'indice de cette valeur sera la plus commune de la valeur dans la liste d'origine.
C'est avec l'hypothèse (ce qui est généralement vrai, dans la pratique) que la taille de l'entrée est beaucoup plus grande que la valeur maximale de l'entrée. Sinon, vous pouvez faire une passe à travers le tableau à l'avance et assurez-vous que ce n'est pas le cas, et d'utiliser un autre algorithme, si elle est. Cela n'empêche pas l'exécution.
Votre hypothèse semble la limitation et de la contre-nature. La seule hypothèse que vous pouvez faire pour la plage de valeurs est qu'ils sont bornées par les limites d'un int, quelle que soit la taille de la matrice.
Juste assez. Quel est le problème avec ma solution de contournement?
Je pense que la partie je suis en désaccord, c'est que votre approche est O(1) de l'espace. Compte tenu de la limitation des apports doivent être entiers, la taille de la matrice de vous créer varie en fonction de l'entrée. Il n'est donc pas constante. La seule façon vous pouvez dire que c'est constant (et donc O(1)) si vous dites que vous toujours créer un tableau de taille égale au nombre de discrètes valeurs int (4 milliards), ce qui n'est pas très utile. Je ne pense pas qu'une solution de "essayer quelque chose d'autre de cette entrée" aide, sauf si vous spécifiez précisément ce que quelque chose d'autre.
OriginalL'auteur maxko87
Ce n'est pas une réponse complète, mais il devrait aider à jeter une certaine lumière sur les raisons de ce problème est difficile.
Considérons que nous voulons concevoir un algorithme, qui fait un balayage sur le tableau (dans l'ordre) de trouver l'élément commun. Lors de l'exécution de notre algorithme, il est permis de garder une certaine structure de données
S
. Nous allons voir comment beaucoup d'informations, il y a dansS
, et donc si l'on est capable de le contenir dansO(1)
mémoire.Dire que notre algorithme a traité le premier
k
éléments de la matrice. MaintenantS
peut nous dire la plupart élément commun dans la gammea[0..k]
. Cependant, dire que nous savions que lek+1
'st élément, nous savons aussi le plus commun élément dans la gammea[0..k+1]
. Si elle ne pouvait pas le cas, notre algorithme ne fonctionne pas sin
étaitk+1
. Plus généralement, la connaissance des élémentsa[k..m]
etS
, nous savons que la plupart élément commun dansa[0..m]
.On peut utiliser l'argument ci-dessus pour extraire des informations à partir de
S
. Dis, on travaille avec des entiers dans la gamme[0,u]
(il doit y avoir de gamme si le tableau d'origine a pris l'espaceO(n)
). Si l'origine de la plupart élément commun est5
, puis nous ajoutons0
's jusqu'à ce que le plus commun élément change. Si cela a prisc
zéros,a[0..k]
doit avoir contenuc
plus5
's que0
'. En répétant cet argument nous recevons beaucoup d'équations linéaires qui nous permet de résoudre de dire exactement combien de fois chacun des éléments[0,u]
étaient présents dansa[0..k]
.Cela nous dit que toute structure de données qui effectue un balayage, pourrait tout aussi bien stocker le nombre de toutes les le vu des éléments (dans certains compressé façon). Si vous êtes intéressé par les maths, la stockées après avoir vu
n
nombres estlog(n+u-1 choose n)
qui est le journal de bord de le nombre de façons de partitionn
impossible de distinguer les éléments dansu
distinguer les bacs. C'est plus quelog(u^n/n!) >= nlogu-nlogn
.Conclusion: Tout algorithme qui ne fait qu'un passage de la matrice devrez utiliser autant de mémoire qu'il faut pour stocker tous les comtes vu jusqu'à présent. Si
n
est petite par rapport àu
cela correspond à stockern
mots de la mémoire.(Eh bien, au lieu de la mémoire supplémentaire, nous pouvons également remplacer le tableau existant).
Il y a beaucoup plus à découvrir ici. E. g. comment passes multiples et affectent les arguments ci-dessus. Cependant, je pense que je devrais arrêter à ce point :), mais il ne semble pas probable pour moi que tout le temps linéaire de l'algorithme, avec un grand
u
, sera en mesure de s'en tirer avecO(1)
de la mémoire supplémentaire.ulogn
bits (u
bacs de chaque mesure de compter jusqu'àn
). Sin
est d'environ la taille deu
sa solution, c'est bien. Sin
est plus petit queu
sa solution peut encore être efficace en utilisant une table de hachage, cependant il ne sera pas de la constante de l'espace.Voici une autre preuve de la même chose theory.stanford.edu/~trevisan/cs154-12/notestream.pdf
Vous pouvez en faire plus qu'une seule passe, et encore être en O(n)... (commentaire de quelqu'un - précieuses informations ici, dans cette réponse, mais je sais que, en supposant que 1 pass est plus stricte que l'exigence de O(n), qui est ce que le problème demande)
Droit, tout dépend du modèle. Il est également important de savoir si l'entrée est alors stocké dans la mémoire en lecture seule. Sinon, le radixsort approche serait de travailler. Je ne sais pas quelle situation qui correspondrait bien.
Pour le dire d'une autre façon de détruire votre tableau d'entrée implique de multiples pistes de votre algorithme aurez besoin d'un tableau initialisé dans le temps et dans l'espace, de sorte qu'il n'est pas pratique, comme vous l'avez dit. Ayant pré-initialisé en lecture-seule la mémoire peut exister dans une série ou parallèle de l'algorithme et donc l'initialisation de vous faire à l'avant est une chose une seule fois. Si j'ai quelques immuable structure de données puis-je écrire de petits compacts de l'espace et du temps des algorithmes permettant d'analyser en parallèle et plus et plus...
OriginalL'auteur Thomas Ahle
Si vous voulez avoir fixé l'espace pour trouver le plus commun élément-vous besoin d'avoir un nombre maximum de bits pour un élément. Si vous n'avez pas, alors grande entrée tableaux pourraient avoir de plus grandes d'entrée des nombres tels que la bits pour représenter le nombre est plus grand que votre fixe d'espace pour stocker le résultat.
Supposons que
k
est la longueur du plus grand nombre à prendre en charge. Si vous essayez d'naïvement créer un tableau de2^k
seaux pour compter les occurrences de chaque numéro (compteur de tri), vous pourriez recevoir un tableau contenant le même nombre, dans ce cas, votre algorithme devoirlog(n)
d'espace pour stocker la somme.[*]Si l'on regarde une version plus simple du problème de déterminer si oui ou non il y a plus de
1
's ou0
's dans l'entrée, je pense que vous avez besoin d'une pile pour ce faire (vous stockez combien1
ou0
est à la tête), et donc de la constante de l'espace n'est tout simplement pas possible, même si l'on limite l'entrée de la longueur dek = 1
bits.Votre problème est plus général (
k > 1
, mais encore fixé), et aurait besoin de non-constante de l'espace, de sorte qu'il n'est pas possible, car la question est formulée.[*] Si vous assumez les compteurs ont
O(1)
de la complexité de l'espace, alors vous pouvez prendre le comptoir trier approche, bien que, ce faisant, vous avez placé une limite supérieure à la taille maximale de votre tableau d'entrée (qui peut ou peut ne pas être acceptable): En termes dek
, le nombre maximum de bits pour un élément de saisie de votre tableau et en termes dec
le nombre maximum de bits dans votre compteur de votre tableau peut avoir au plus2^k * 2^c
éléments (l'un des compteurs serait débordement sinon sur l'élément suivant). Pour résoudre ce problème, vous pouvez ajouter unO(1)
pas de temps pour décrémenter vos compteurs de sorte que la valeur minimale est toujours0
après chaque élément est traité si tous les compteurs sont non-0
, ce qui les rend relative plutôt qu'absolue. Cela prendO(1)
temps parce que si tous sont non nuls vous avez seulement besoin de décrémenterO(2^k) = O(1)
compteurs par1
si vous effectuer sur chaque élément. Tandis que l'algorithme peut maintenant traiter certains arbitrairement grandes entrées, une entrée de tableau qui a un sous-tableau de telle sorte que deux valeursa
etb
sont telles quecount(a) - count(b) > 2^c = max(counter)
à l'aide d'une contre-stratégie échoue pour certains intrants. En fait, une conséquence de s'appuyer sur unO(1)
espace complexité compteur approche est que tous les tableaux qui commencent par2^c + 1
éléments identiques ne peuvent pas être traitées par cet algorithme.Je pense que l'OP veut dire que si j'ai un tableau d'entrée avec
n
éléments, puis une table de hachage, qui stocke si oui ou non j'ai vu un certain nombre, prend jusqu'àn
éléments à l'intérieur d'elle et, dans son état final (après tout redimensionne en raison de dépasser son seuil), estO(n)
de la mémoire. LeO(1)
"compteur" est un équivalent d'un peu de dire si oui ou non je l'ai vu - n'est pas un compteur de dire combien j'en ai vu... à moins que l'OP a donné d'indication contraire.Ok, un vecteur de bits prendrait seulement O(n) bits. Une table de hachage sera généralement nlogn, même si les valeurs sont des bits, car il a besoin de stocker les clés pour l'égalité de la vérification. (Peut-être parfaites de hachage). Mais comment savoir si nous avons vu une valeur avant de l'aider à résoudre le problème? Il semble être nous avons besoin de connaître le nombre.
Quand vous dites "Une table de hachage sera généralement nlogn..." qu'est-ce que votre "n"? Il ne nous aide pas à résoudre le problème; nous aurions besoin de les compter (ou vraiment juste combien à l'avance quelque chose est dans le cas où il finit tombe derrière plus tard - vous n'avez pas besoin de calculer le nombre réel de calculer la majorité) - vous avez raison, mais je pense que l'OP n'a probablement pas savoir quelles structures de données seraient utiles ou pas pour ce problème; je pense que l'OP du point de vue de clarifier avec un exemple de quelque chose qui a été "contre les règles".
Oui, OP destinés à la table pour stocker les comtes, et considère ceci comme O(n) de la mémoire. Ainsi, l'un compteur est O(1) de la mémoire. C'est mon point de vue.
OriginalL'auteur Words Like Jared
c'est mon script pour lire plus commun élément dans un tableau
OriginalL'auteur ashish yadav