finden die vier Elemente in der Reihe, deren Summe gleich einer gegebenen Zahl X
Ich brauche Hilfe beim finden eines Algorithmus, der feststellt:
- vier Elemente in array
- deren Summe gleich einer gegebenen Zahl X
- in O(n^2*log(n))
lieber in pseudo-code oder c,c++
- Klingt nach Hausaufgaben
- Klingt wie Sie brauchen eine Methode zu finden, alle Permutationen von 4 eindeutige Indizes.
- Sind die zahlen größer als null? Sind alle zahlen einzigartig?
- Jede Einschränkung auf X oder zahlen?
- Meinst du, dass Sie möchten, schreiben Sie eine Funktion, die einen
array
seinelength
, und einvalue
und zurückgeben eines Satzes von 4 Mitgliedern derarray
deren Summevalue
? Tun Sie es möchten, geben Sie die Menge aller möglichen Sätze von 4 Mitgliedern, deren Summevalue
? Was, wenn es keines gefunden? - Hinzugefügt tag Hausaufgaben da es schon eine Stunde und nichts sagt, ist es nicht.
- Für was es Wert ist, ich erinnere mich an das problem vor und hörenden Menschen mit Lösungen mit einer Art
n^2
Elemente (vermutlich die Summen von jedem paar) und dannn^2
binäre Suche, was in der gewünschten Komplexität. Ich habe nie herausgefunden, wie Sie sich mit bestimmten Indizes Probleme jedoch. Ich dachte, ich würde teilen, falls jemand will, verfolgen diesen Ansatz. - die zahlen sind nicht eindeutig oder positiv, ich brauche nur eine option, nicht alle Permutationen von 4 zahlen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du kannst es in O(n^2). Funktioniert gut mit dupliziert und negative zahlen.
Bearbeiten, als Andre bemerkt im Kommentar, die Zeit ist mit der Nutzung der hash, die hat 'worst-case' (obwohl, es ist weniger wahrscheinlich als ein Sechser im Lotto). Aber Sie können auch ersetzen die hashtable mit ausgeglichener Baum (Tree Map in java) und Sie bekommen garantiert stabile O(n^2 * log(n)) Lösung.
Hashtable
sums
speichern alle möglichen Summen von zwei verschiedenen Elementen. Für jede SummeS
es gibt paar von Indizesi
undj
so dassa[i] + a[j] == S
undi != j
. Aber zunächst ist es leer, wir füllen es auf dem Weg.Sagen wir
X = a[1] + a[3] + a[7] + a[10]
. Diese Summe wird gefunden, wenni = 7
,j = 10
undrest = a[1] + a[3]
(Indizes 1 und 3 gefunden bei hash)Wie ein paar andere Poster, es kann getan werden mit einem hash in O(n^2)
Missbrauchen die Tatsache, dass kein Speicher beschränken angegeben ist. Und mit den üblichen divide and conquer Ansatz.
Anzahl aller Permutationen für 4 Anzahl der Teilmengen ist C(n,4) und ist O(n^4). Anzahl aller Permutationen für 2 zahlen ist C(n,2) und O(n^2). O(n^2) scheint OK zu sein für die Aufgabe.
A
mitn
ElementeX
.B
mit n^2 Elemente (auch die Erinnerung an die Untergruppen). Wir bezeichnen alsS[B[i]]
die Untergruppe (bestehend aus den zwei zahlen), deren SummeB[i]
.B
O(n^2*log(n^2)).Spaziergang durch das array
B
(O(n^2))i = [0,n^2)
und schnelle SucheO(log(n^2)) = O(log(n))
für die es Wert(X - B[i])
. Möglicherweise gibt es mehrere von Ihnen (aber nicht mehr als n^2).4.1. Gehen Sie durch alle Elemente mit dem Wert
(X - B[i])
mit indexk
.4.2. Überspringen Sie die Elemente
B[k]
woS[B[k]]
schneidet mitS[B[i]]
. Kreuzung von zwei sets mit zwei zahlen berechnet werden kann, in O(1).4.3 Wenn
k
ist der index ein element, woB[i] + B[k] == X
undS[B[k]]
keine Schnittmenge mitS[B[i]]
, dann ist die Summe der SätzeS[B[k]]
undS[B[i]]
sind die vier gesuchten zahlen.Leistung ist:
O( n^2 + n^2*log(n^2) + n^2*log(n^2) ) = O( n^2 * log(n^2) ) = O( n^2 * log(n) )
Schritt vier, wenn wir die Iteration über die mehrere übereinstimmende Elemente
B
mit geschachtelten Schleife. Dennoch, die Gesamtzahl der Iterationen der beiden geschachtelten Schleifen ist begrenzt durch die|B|
ist O(n^2). Die Suchfunktion ist nicht die übliche Variante, aber die eine, die findet das passende element mit dem niedrigsten index. (Alternativ kann man verwenden, um die üblichenbsearch
und da könnten wir landeten in der Mitte, zwei benachbarte Schleifen, überprüfen der Elemente in beide Richtungen.)log(n^2)
ist2log(n)
sind, so sind Sie nicht mehr als die Zeit-Komplexität. Dies wird jedoch nicht für doppelte Elemente zu. Weitere Prüfungen benötigt werden, aber es ist möglich. Zum Beispiel bei einem array[1, 2, 3]
und die Summen[ 1+2, 1+3, 2+3 ]
gewünschte Summe9
finden mit4 + 5
, aber wir zählen 3 doppelt dann.Einen funktionierenden Java-Lösung des algo. zur Verfügung gestellt von Nikita Rybak oben..
1) Erstellen Sie ein array aller möglichen pair Summen [O(N^2)]
2) Sortieren Sie das array in aufsteigender Reihenfolge [O(N^2 * Log N)]
3) Jetzt wird dieses problem reduziert sich auf der Suche nach 2 zahlen in einem sortierten array, dass die Summe einer gegebenen Zahl X, in der linearen Zeit. Verwenden Sie 2 Zeiger: einen LOW-pointer beginnend bei dem niedrigsten Wert, und ein HOHER Zeiger ausgehend vom höchsten Wert. Wenn die Summe zu niedrig ist, vorab zu GERING. Wenn die Summe zu hoch ist, Voraus HOCH (rückwärts). Schließlich werden Sie finden, dass ein paar oder einander kreuzen (dies kann leicht nachgewiesen). Dieser Prozess dauert lineare Zeit in der Größe des Arrays, d.h. in O(N ^ 2)
Dies ergibt eine Gesamtzeit von O(N^2 * log N), wie erforderlich.
HINWEIS : Diese Methode verallgemeinert werden kann für die Lösung der Fall von M zahlen in O(M * N^(M/2) * log N) Zeit.
-- EDIT --
Eigentlich meine Antwort ist sehr ähnlich zu Dummy00001 Antwort, mit Ausnahme der letzten-lookup, wo ich eine schnellere Methode (obwohl die Komplexität ist die gleiche...)
sum=18
. Unda = {2,3,4,5,7,9,10}
jetzta[0]+a[1]=5
unda[2]+a[5]=13
, soa[0]+a[1]+a[2]+a[5]=18
. Abera[1]+a[2]=7
unda[0]+a[5]=11
dahera[0]+a[1]+a[2]+a[5]=18
. so wird Ihre Lösung drucken Sie diese zwei anstelle von 1. So, wie Sie dieses Problem anzugehen. Danke.Klingt wie Hausaufgaben zu mir. Aber hier ist, was ich tun würde.
Zuerst Sortieren Sie die zahlen (gibt ' s Ihre n*log(n)).
Erstellen Sie jetzt Zeiger auf die Liste, initialisiert es mit den ersten 4 zahlen. Sobald Sie das haben, überprüfen Sie die Summe Ihrer 4 aktuellen zahlen mit der Gesamtsumme. Es sollte weniger als oder gleich zu Ihrer Suche Summe (wenn es nicht, können Sie beenden zu früh). Alles was Sie jetzt tun müssen, ist die traverse rest der Liste abwechselnd ersetzen Sie Ihren Zeiger mit dem aktuellen Wert in der Liste. Diese müssen nur einmal (oder wirklich im schlimmsten Fall 4 mal), so ist Ihre andere n, wodurch n^2*log(n)
Müssen Sie verfolgen, eine gewisse Logik zu wissen, ob Sie sind über/unter Summe und was als Nächstes zu tun, aber das überlasse ich als Ihre Hausaufgabe.
Werde ich nicht beantworten Ihre Frage vollständig, da ich denke, dass es Hausaufgaben und denke auch, dass dies einfach möglich ist. Aber ich denke, dass ich weiß, warum Sie Schwierigkeiten haben, eine Antwort, so werde ich Ihnen helfen, ein wenig heraus.
Erstens, Sie sollten in die Rekursion. Das bedeutet, dass das aufrufen einer Funktion aus sich selbst heraus.
Zweiten, sollten Sie eine helper-Funktion, die aufgerufen wird die Funktion, die Sie schreiben möchten. Diese Funktion nehmen sollten Argumente:
- ein array von zahlen
- die Länge des Arrays
- der Wert, den Sie möchten, finden Sie die Mitglieder, dass die Summe bis zu
- die Zahl der Mitglieder des Arrays, die Sie summieren wollen
Diese Funktion wird aufgerufen werden, indem Sie Ihr eine andere Funktion übergeben und eine 4 für das Letzte argument. Es wird dann selbst aufrufen, anpassen der Argumente, wie es versucht, um Ergebnisse zu finden, die durch partielle Versuch und Irrtum.
edit 2
Auf weiter dachte, merkte ich, dass dies nicht O(n^2), als ich behauptete, früher (ich geistig beschönigt die Mitte-Schritte). Es ist begrenzt durch n^4, kann aber eine untere Grenze als durch reichliche Gelegenheit zu kurzen Schnitt in vielen Fällen. Ich glaube nicht, dass diese kurze Schnitt verbessert es auf den Punkt, von n^2, wenn.
finden vier Elemente in der Reihe, deren Summe gleich einer gegebenen Zahl X
für mich folgenden Algorithmus arbeitet:
Habe ich geschrieben ein O(N^^2) Laufzeit-Funktion, welche nicht mit hashtables, sondern die negativen zahlen und die doppelten zahlen scheinbar OK. Ich Griff negativen zahlen in ein integer-array, indem eine große positive Zahl(z.B. 100), um die zahlen im array. Dann, ich passe mich dem Ziel von
target += (4 * 100)
. Dann, wenn ich ein Ergebnis habe ich subtrahieren sich die 100 von den ganzen zahlen in das Ergebnis ein. Hier ist mein code und Testfälle: Bitte lassen Sie mich wissen, wenn dies o(N^^2) Zeit-Komplexität.Dieses problem reduziert werden kann, zu finden, die alle Kombinationen der Länge 4. Für jede Kombination der so erhaltenen, die Summe der Elemente und prüfen, ob es gleich X.
Dieses problem kann als eine Abwandlung von pascals Identität,
hier ist der vollständige code :
entschuldigen Sie bitte, wie sich der code in java :
}
Beispiel für die Eingabe :
Ausgabe : :