Diese Frage wurde mir in einem Vorstellungsgespräch gestellt und ich würde gerne wissen, wie andere sie lösen würden. Ich bin mit Java am besten vertraut, aber Lösungen in anderen Sprachen sind willkommen.
Geben Sie bei einem Array von Zahlen
nums
ein Array von Zahlen zurückproducts
, wobeiproducts[i]
das Produkt von allen istnums[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]
Sie müssen dies
O(N)
ohne Division tun .
[interview-questions]
Tags. Haben Sie einen Link, wenn Sie ihn gefunden haben?Antworten:
Eine Erklärung der Polygenelubricants- Methode lautet: Der Trick besteht darin, die Arrays zu konstruieren (im Fall für 4 Elemente).
Beides kann in O (n) erfolgen, indem am linken bzw. rechten Rand begonnen wird.
Wenn Sie dann die beiden Arrays Element für Element multiplizieren, erhalten Sie das gewünschte Ergebnis
Mein Code würde ungefähr so aussehen:
Wenn Sie auch im Weltraum O (1) sein müssen, können Sie dies tun (was meiner Meinung nach weniger klar ist).
quelle
v_i=0
ist der i-te Element der einzige Eintrag ungleich Null im Ergebnis. Ich vermute jedoch, dass das Hinzufügen eines Durchlaufs zum Erkennen und Zählen der Nullelemente die Klarheit der Lösung beeinträchtigen und in den meisten Fällen wahrscheinlich keinen wirklichen Leistungsgewinn erzielen würde.Hier ist eine kleine rekursive Funktion (in C ++), um die Modifikation an Ort und Stelle durchzuführen. Es erfordert jedoch O (n) zusätzlichen Speicherplatz (auf dem Stapel). Angenommen, das Array befindet sich in a und N enthält die Array-Länge, die wir haben
quelle
num[N-1]
. Auf dem Rückweg berechnet es dann den zweiten Teil der Multiplikation, der dann zum Ändern des vorhandenen Zahlenarrays verwendet wird.Hier ist mein Versuch, es in Java zu lösen. Entschuldigung für die nicht standardmäßige Formatierung, aber der Code weist viele Duplikate auf, und dies ist das Beste, was ich tun kann, um ihn lesbar zu machen.
Die Schleifeninvarianten sind
pi = nums[0] * nums[1] *.. nums[i-1]
undpj = nums[N-1] * nums[N-2] *.. nums[j+1]
. Deri
linke Teil ist die "Präfix" -Logik, undj
der rechte Teil ist die "Suffix" -Logik.Rekursiver Einzeiler
Jasmeet gab eine (schöne!) Rekursive Lösung; Ich habe daraus diesen (abscheulichen!) Java-Einzeiler gemacht. Es werden Änderungen an Ort und Stelle mit
O(N)
temporärem Speicherplatz im Stapel vorgenommen.quelle
Michael Andersons Lösung in Haskell übersetzen:
quelle
Schleichende Umgehung der Regel "keine Teilung":
quelle
Los geht's, einfache und saubere Lösung mit O (N) -Komplexität:
quelle
C ++, O (n):
quelle
Auf)
quelle
Hier ist meine Lösung in modernem C ++. Es macht Gebrauch
std::transform
und ist ziemlich leicht zu merken.Online-Code (Zauberstabbox).
quelle
Dies ist O (n ^ 2), aber f # ist soooo schön:
quelle
Berechnen Sie das Produkt der Zahlen links und rechts von jedem Element vor. Für jedes Element ist der gewünschte Wert das Produkt der Produkte seiner Nachbarn.
Ergebnis:
(UPDATE: Jetzt schaue ich genauer hin, dies verwendet die gleiche Methode wie Michael Anderson, Daniel Migowski und Polygenelubricants oben)
quelle
Tricky:
Verwenden Sie Folgendes:
Ja, ich bin sicher, ich habe einige i-1 anstelle von i verpasst, aber das ist der Weg, um es zu lösen.
quelle
Es gibt auch eine nicht optimale O (N ^ (3/2)) - Lösung. Es ist jedoch ziemlich interessant.
Verarbeiten Sie zuerst jede Teilmultiplikation der Größe N ^ 0,5 vor (dies erfolgt in O (N) -Zeitkomplexität). Dann kann die Berechnung für das Vielfache der anderen Werte jeder Zahl in 2 * O (N ^ 0,5) durchgeführt werden (warum? Weil Sie nur die letzten Elemente anderer ((N ^ 0,5) - 1) Zahlen multiplizieren müssen. und multiplizieren Sie das Ergebnis mit ((N ^ 0,5) - 1) Zahlen, die zur Gruppe der aktuellen Zahl gehören). Wenn man dies für jede Zahl tut, kann man O (N ^ (3/2)) Zeit bekommen.
Beispiel:
4 6 7 2 3 1 9 5 8
Teilergebnisse: 4 * 6 * 7 = 168 2 * 3 * 1 = 6 9 * 5 * 8 = 360
Um den Wert 3 zu berechnen, muss man die Werte 168 * 360 der anderen Gruppen multiplizieren und dann mit 2 * 1.
quelle
Diese Lösung habe ich mir ausgedacht und fand es so klar, was denkst du?
quelle
arr = [1, 2, 3, 4, 5] prod = [] produktiviere (arr, prod, 0) drucke prod
quelle
Um hier vollständig zu sein, ist der Code in Scala:
Dadurch wird Folgendes ausgedruckt:
Das Programm filtert das aktuelle Element heraus (_! = Element); und multiplizieren Sie die neue Liste mit der Methode reduLeft. Ich denke, dies ist O (n), wenn Sie Scala View oder Iterator für Lazy Eval verwenden.
quelle
Basierend auf der Antwort von Billz - Entschuldigung, ich kann keinen Kommentar abgeben, aber hier ist eine Scala-Version, die doppelte Elemente in der Liste korrekt behandelt und wahrscheinlich O (n) ist:
kehrt zurück:
quelle
Ich habe hier meine Javascript-Lösung hinzugefügt, da ich niemanden gefunden habe, der dies vorschlägt. Was ist zu teilen, außer zu zählen, wie oft Sie eine Zahl aus einer anderen Zahl extrahieren können? Ich habe das Produkt des gesamten Arrays berechnet, dann über jedes Element iteriert und das aktuelle Element bis Null subtrahiert:
quelle
Ich bin an C # gewöhnt:
quelle
Wir können zuerst das
nums[j]
(Woj != i
) von der Liste ausschließen und dann das Produkt des Restes erhalten; Das Folgende ist einpython way
, um dieses Rätsel zu lösen:quelle
Nun, diese Lösung kann als die von C / C ++ angesehen werden. Nehmen wir an, wir haben ein Array "a", das n Elemente wie a [n] enthält, dann wäre der Pseudocode wie folgt.
quelle
Eine weitere Lösung: Division verwenden. mit zweimaliger Durchquerung. Multiplizieren Sie alle Elemente und teilen Sie sie durch jedes Element.
quelle
quelle
Hier ist mein Code:
quelle
Hier ist ein leicht funktionierendes Beispiel mit C #:
Ich bin mir nicht ganz sicher, ob dies O (n) ist, da die erstellten Funcs halb rekursiv sind, aber meine Tests scheinen darauf hinzudeuten, dass es zeitlich O (n) ist.
quelle
// Dies ist die rekursive Lösung in Java. // Wird vom Hauptprodukt wie folgt aufgerufen (a, 1,0);
quelle
Eine saubere Lösung mit O (n) Laufzeit:
Erstellen Sie ein endgültiges Array "Ergebnis" für ein Element i,
quelle
quelle
Hier ist ein weiteres einfaches Konzept, das das Problem löst
O(N)
.quelle
Ich habe eine Lösung mit
O(n)
räumlicher undO(n^2)
zeitlicher Komplexität, die unten angegeben ist.quelle