On m'a posé cette question lors d'un entretien d'embauche et j'aimerais savoir comment les autres pourraient la résoudre. Je suis plus à l'aise avec Java, mais les solutions dans d'autres langues sont les bienvenues.
Étant donné un tableau de nombres,,
nums
renvoie un tableau de nombresproducts
, oùproducts[i]
est le produit de tousnums[j], j != i
.Input : [1, 2, 3, 4, 5] Output: [(2*3*4*5), (1*3*4*5), (1*2*4*5), (1*2*3*5), (1*2*3*4)] = [120, 60, 40, 30, 24]
Vous devez le faire
O(N)
sans utiliser de division.
[interview-questions]
balise à sa recherche. Avez-vous un lien si vous l'avez trouvé?Réponses:
Une explication de la méthode des lubrifiants polygéniques est: L'astuce consiste à construire les tableaux (dans le cas de 4 éléments)
Les deux peuvent être effectués en O (n) en commençant respectivement par les bords gauche et droit.
Ensuite, multiplier les deux éléments du tableau par élément donne le résultat requis
Mon code ressemblerait à ceci:
Si vous devez également être O (1) dans l'espace, vous pouvez le faire (ce qui est moins clair à mon humble avis)
la source
v_i=0
que la seule entrée non nulle dans le résultat est le ième élément. Cependant, je soupçonne que l'ajout d'une passe pour détecter et compter les éléments nuls nuirait à la clarté de la solution, et ne ferait probablement pas de réel gain de performance dans la majorité des cas.Voici une petite fonction récursive (en C ++) pour faire la modofication en place. Il nécessite cependant O (n) espace supplémentaire (sur la pile). En supposant que le tableau est dans a et que N contient la longueur du tableau, nous avons
la source
num[N-1]
; puis sur le chemin du retour il calcule la seconde partie de la multiplication qui sert ensuite à modifier le tableau numérique en place.Voici ma tentative de le résoudre en Java. Toutes mes excuses pour le formatage non standard, mais le code a beaucoup de duplication, et c'est le mieux que je puisse faire pour le rendre lisible.
Les invariants de boucle sont
pi = nums[0] * nums[1] *.. nums[i-1]
etpj = nums[N-1] * nums[N-2] *.. nums[j+1]
. Lai
partie de gauche est la logique «préfixe» et laj
partie de droite est la logique de «suffixe».Une ligne récursive
Jasmeet a donné une (belle!) Solution récursive; Je l'ai transformé en ce (hideux!) One-liner Java. Il effectue des modifications sur place , avec
O(N)
un espace temporaire dans la pile.la source
Traduire la solution de Michael Anderson en Haskell:
la source
Contournement sournois de la règle du "pas de division":
la source
Voilà, solution simple et propre avec une complexité O (N):
la source
C ++, O (n):
la source
Sur)
la source
Voici ma solution en C ++ moderne. Il utilise
std::transform
et est assez facile à retenir.Code en ligne (wandbox).
la source
C'est O (n ^ 2) mais f # est tellement beau:
la source
Précalculez le produit des nombres à gauche et à droite de chaque élément. Pour chaque élément, la valeur souhaitée est le produit des produits de ses voisins.
Résultat:
(MISE À JOUR: maintenant je regarde de plus près, cela utilise la même méthode que Michael Anderson, Daniel Migowski et les lubrifiants polygéniques ci-dessus)
la source
Rusé:
Utilisez le suivant:
Oui, je suis sûr que j'ai manqué un i-1 au lieu d'un i, mais c'est la façon de le résoudre.
la source
Il existe également une solution non optimale O (N ^ (3/2)) . C'est tout à fait intéressant, cependant.
Tout d'abord prétraitez chaque multiplication partielle de taille N ^ 0,5 (ceci est fait en complexité temporelle O (N)). Ensuite, le calcul pour le multiple des autres valeurs de chaque nombre peut être effectué en 2 * O (N ^ 0,5) temps (pourquoi? Parce que vous n'avez besoin de multiplier que les derniers éléments des autres ((N ^ 0,5) - 1) nombres, et multipliez le résultat par ((N ^ 0.5) - 1) nombres qui appartiennent au groupe du nombre courant). En faisant cela pour chaque nombre, on peut obtenir le temps O (N ^ (3/2)).
Exemple:
4 6 7 2 3 1 9 5 8
résultats partiels: 4 * 6 * 7 = 168 2 * 3 * 1 = 6 9 * 5 * 8 = 360
Pour calculer la valeur de 3, il faut multiplier les valeurs des autres groupes 168 * 360, puis par 2 * 1.
la source
Cette solution que j'ai trouvée et je l'ai trouvée si claire que pensez-vous !?
la source
arr = [1, 2, 3, 4, 5] prod = [] productify (arr, prod, 0) prod impression
la source
Pour être complet voici le code en Scala:
Cela imprimera ce qui suit:
Le programme filtrera l'élément actuel (_! = Elem); et multipliez la nouvelle liste avec la méthode reductionLeft. Je pense que ce sera O (n) si vous utilisez la vue scala ou Iterator pour l'évaluation paresseuse.
la source
Basé sur la réponse de Billz - désolé, je ne peux pas commenter, mais voici une version scala qui gère correctement les éléments en double dans la liste, et est probablement O (n):
Retour:
la source
Ajout de ma solution javascript ici car je n'ai trouvé personne suggérant cela. Qu'est-ce que diviser, sauf pour compter le nombre de fois où vous pouvez extraire un nombre d'un autre nombre? J'ai calculé le produit du tableau entier, puis j'ai parcouru chaque élément et j'ai soustrait l'élément actuel jusqu'à zéro:
la source
Je suis habitué à C #:
la source
Nous pouvons d'abord exclure le
nums[j]
(wherej != i
) de la liste, puis obtenir le produit du reste; Ce qui suit est unpython way
pour résoudre ce puzzle:la source
Eh bien, cette solution peut être considérée comme celle du C / C ++. Disons que nous avons un tableau "a" contenant n éléments comme a [n], alors le pseudo-code serait comme ci-dessous.
la source
Encore une solution, en utilisant la division. avec double traversée. Multipliez tous les éléments, puis commencez à le diviser par chaque élément.
la source
la source
Voici mon code:
la source
Voici un exemple légèrement fonctionnel, utilisant C #:
Je ne suis pas tout à fait certain que ce soit O (n), en raison de la semi-récursivité des Funcs créés, mais mes tests semblent indiquer que c'est O (n) dans le temps.
la source
// Ceci est la solution récursive en Java // Appelé comme suite du produit principal (a, 1,0);
la source
Une solution soignée avec le runtime O (n):
Créer un tableau final "résultat", pour un élément i,
la source
la source
Voici un autre concept simple qui résout le problème en
O(N)
.la source
J'ai une solution avec une complexité
O(n)
spatiale etO(n^2)
temporelle fournie ci-dessous,la source