Comment trouver un double élément dans un tableau de déplacés nombres entiers consécutifs?
Je suis récemment tombé sur une question quelque part:
Supposons que vous disposez d'un tableau de 1001 entiers. Les entiers sont dans un ordre aléatoire, mais vous savez tous les entiers entre 1 et 1000 (inclus). En outre, chaque numéro s'affiche qu'une seule fois dans le tableau, sauf pour un certain nombre, qui se produit deux fois. Supposons que vous pouvez accéder à chaque élément du tableau qu'une seule fois. Décrire un algorithme pour trouver le certain nombre. Si vous avez utilisé auxiliaire de stockage dans votre algorithme, pouvez-vous trouver un algorithme qui n'en a pas besoin?
Ce que je veux savoir, c'est la deuxième partie, c'est à dire, sans l'aide d'auxiliaires de stockage. Avez-vous une idée?
- assez sûr que cela a été demandé avant, mais impossible de trouver l'exacte qn. le total de la n des entiers dans l'ordre et la répétition de l'entier x est x + n(n-1)/2.
- Pouvez vous s'il vous plaît question de modification du titre pour quelque chose de plus descriptif? Peut-être que "Trouver dupliquer l'élément de tableau avec des contraintes particulières"
- une autre propriété mathématique que vous pouvez utiliser ici est la factorielle. (n1 * n2 * .. ) / n! donne le nombre requis. 1000! factorielle n'est pas que les grandes d'un certain nombre pour être honnête, justinwhite.com/big-calc/1000.html
- Yep, 1000! n'est pas que les grandes d'un certain nombre seulement 559 chiffres pour remplir le reste de la zone de commentaire et un autre 2921 chiffres-dessus de la limite... 🙂
- Plus dur (pas de passage unique en O(1) solution de l'espace) version de cette question est "Algorithme pour déterminer si le tableau contient n...n+m?" stackoverflow.com/questions/177118/...
- Question légèrement différente, avec la même réponse: stackoverflow.com/questions/35185/...
- Nouveau: stackoverflow.com/questions/1089987/...
- Dupliquer: stackoverflow.com/questions/555744/...
- astuce de question - réponse a été traîner aussi longtemps que la question a :-/
- Le problème est que, après chaque numéro s'affiche qu'une seule fois (nous avons 1001 différents nombres entiers) + 1 répétées nombre = 1002 entiers
Vous devez vous connecter pour publier un commentaire.
Juste ajouter tout en haut, et soustraire le montant total que vous attendez si seulement 1001 numéros ont été utilisés à partir de cela.
Par exemple:
Mise à jour 2: Certaines personnes pensent que l'utilisation de XOR pour trouver le numéro en double est un hack et astuce. À laquelle ma réponse officielle est: "je ne suis pas à la recherche d'un numéro en double, je suis à la recherche pour un double motif dans un tableau des ensembles de bits. Et XOR est certainement adapté de mieux que d'AJOUTER à manipuler des ensembles de bits". 🙂
Mise à jour: Juste pour le plaisir avant d'aller me coucher, voici "on-line" solution alternative qui ne nécessite aucun stockage supplémentaire (même pas un compteur de boucle), touche chaque élément du tableau qu'une seule fois, est non destructif et n'est pas adaptée à tous 🙂
Noter que le compilateur fait calculer la seconde moitié de cette expression au moment de la compilation, l ' "algorithme" va exécuter exactement 1002 opérations.
Et si l'élément de tableau de valeurs sont connues au moment de la compilation, le compilateur d'optimiser l'intégralité de la déclaration d'une constante. 🙂
Solution originale: Qui ne répond pas aux exigences strictes des questions, même si cela fonctionne pour trouver la bonne réponse. Il utilise un entier supplémentaire de garder le compteur de la boucle, et elle accède à chaque élément du tableau à trois reprises, deux fois à le lire et à l'écrire à l'itération en cours et une fois à lire pour la prochaine itération.
eh Bien, vous avez besoin d'au moins une variable supplémentaire (ou un PROCESSEUR inscrire) pour stocker l'index de l'élément courant que vous allez à travers le tableau.Côté de celle-ci, voici un destructeur algorithme qui peut en toute sécurité à l'échelle pour tout N jusqu'à MAX_INT.
Je laisse l'exercice de comprendre pourquoi cela fonctionne pour vous, un simple conseil :-):
xor
astuces me rendre maladeNon destructive version de la solution par Franci Penov.
Cela peut être fait en faisant usage de la
XOR
de l'opérateur.Permet de dire que nous avons un tableau de taille
5
:4, 3, 1, 2, 2
Qui sont à l'index:
0, 1, 2, 3, 4
Maintenant faire un
XOR
de tous les éléments et tous les indices. Nous obtenons2
, qui est le double de l'élément. Cela se produit parce que,0
ne joue aucun rôle dans la XORing. Le resten-1
indices de paire avec la mêmen-1
éléments dans le tableau et le seulement non appariés élément dans le tableau sera le double.La meilleure caractéristique de cette solution est qu'elle ne souffre pas de problèmes de dépassement que l'on voit à la base de la solution.
Puisque c'est une question d'entrevue, il serait préférable de commencer avec les plus solution d'identifier le dépassement de la limitation et de donner ensuite la
XOR
solution basée sur:)
Cela rend l'utilisation d'une variable supplémentaire n'a donc pas de répondre aux exigences de la question complètement.
{ 1043, 1042, 1044, 1042 }
par XOR-ing avec{ 0, 1042, 1043, 1044 }
.Ajouter tous les nombres. La somme finale sera le 1+2+...+1000+numéro en double.
Pour paraphraser François Penov de la solution.
L' (d'habitude) le problème est: étant donné un tableau d'entiers de longueur arbitraire qui ne contiennent que des éléments répétés d'un même temps de temps, sauf une qui est répété un des moments étranges de temps, de trouver cette valeur.
La solution est:
Votre problème actuel est une adaptation. Le truc, c'est que vous êtes de trouver l'élément qui est répété deux fois, donc il faut adapter la solution pour compenser cette faiblesse.
Qui est ce que François solution n'est en fin de compte, bien qu'il détruit l'ensemble de la baie (de toute façon, il ne pouvait détruire le premier ou le dernier élément...)
Mais puisque vous avez besoin de plus de stockage pour l'indice, je pense que vous serez pardonné si vous utilisez également un supplément entier... La restriction est plus probablement parce qu'ils veulent vous empêcher d'utiliser un tableau.
Il aurait été formulée avec plus de précision si ils avaient exigé
O(1)
de l'espace (1000 peut être vu comme N puisque c'est arbitraire ici).Ajouter tous les nombres. La somme des nombres entiers de 1..1000 (1000*1001)/2. La différence entre ce que vous obtenez est votre numéro.
Si vous savez que nous avons le nombre exact 1-1000, vous pouvez ajouter jusqu'les résultats et de les soustraire
500500
(sum(1, 1000)
) du total. Cela donnera à la répétition de nombre, parce quesum(array) = sum(1, 1000) + repeated number
.Bien, il y a un moyen très simple de faire cela... chacun des nombres entre 1 et 1000 se produit exactement une fois, sauf pour le numéro est répété.... donc, la somme de 1....1000 est 500500. Ainsi, l'algorithme est:
Une solution en ligne en Python
Explication sur pourquoi il fonctionne, c'est dans @Matthieu M. de réponse.
Pas de stockage supplémentaire exigence (à part la variable de boucle).
length
pour le rendre générique.Faire des arguments et des piles d'appels comptent comme des auxiliaires de stockage?
Edit: appel tail version
Un triangle T(n) est la somme de n nombres naturels de 1 à n. Il peut être représenté comme n(n+1)/2. Ainsi, sachant que parmi donnée 1001 nombres naturels, un et un seul nombre est dupliqué, vous pouvez facilement somme de tous les nombres donnés et soustraire T(1000). Le résultat contiendra ce double.
Pour un nombre triangulaire T(n), si n est une puissance de 10, il y a aussi de belles méthode de la découverte de cet T(n), sur la base de la base-10 représentation:
Je soutiens l'addition de tous les éléments, puis en soustrayant de la somme de tous les indices, mais cela ne fonctionnera pas si le nombre d'éléments est très grand. I. e. Il va provoquer un débordement d'entier! J'ai donc imaginé cet algorithme, qui peut être de réduire les chances d'un dépassement d'entier dans une large mesure.
Mais, par cette méthode, je ne vais pas être capable de trouver l'indice à partir duquel le double de l'élément est présent!
Pour cela j'ai besoin de parcourir le tableau d'un autre temps qui n'est pas souhaitable.
Amélioration de Fraci de la réponse repose sur la propriété de XORing valeurs consécutives:
Où:
Ou en pseudo-code/math lang f(n) définie comme (optimisé):
Et dans la forme canonique de f(n) est:
Ma réponse à la question 2:
Trouver la somme et le produit de nombres à partir de 1 -(de) N, dire
SUM
,PROD
.Trouver la somme et le produit des Nombres de 1 - N - x -y, (à supposer x, y manquant), dire mySum, myProd,
Ainsi:
Ainsi:
On peut trouver x,y si résoudre cette équation.
Dans le aux version, vous devez d'abord définir toutes les valeurs -1 et que vous parcourez vérifier si vous avez déjà inséré la valeur de l'auxiliaire de tableau. Si non (la valeur doit être -1, alors), insérer. Si vous avez un doublon, voici votre solution!
Dans celui sans aux, vous pouvez récupérer un élément de la liste et de vérifier si le reste de la liste contient cette valeur. Si il contient, ici, vous l'avez trouvé.