Angesichts eines std::vector
bestimmten Elements, das in aufsteigender Reihenfolge sortiert ist, möchte ich einen Algorithmus entwickeln, der bestimmt, ob die Sammlung zwei Elemente enthält, deren Summe ein bestimmter Wert ist sum
.
Ich habe zwei verschiedene Ansätze mit ihren jeweiligen Kompromissen ausprobiert:
Ich kann den gesamten Vektor scannen und für jedes Element im Vektor die binäre Suche (
std::lower_bound
) auf den Vektor anwenden, um ein Element zu suchen, das der Differenz zwischensum
und dem aktuellen Element entspricht. Dies ist eine O (n log n) -Zeitlösung, die keinen zusätzlichen Speicherplatz benötigt.Ich kann den gesamten Vektor durchlaufen und einen füllen
std::unordered_set
. Dann scanne ich den Vektor und suche für jedes Element imstd::unordered_set
nach dem Unterschied zwischensum
und dem aktuellen Element. Da die Suche in einer Hash-Tabelle im Durchschnitt in konstanter Zeit ausgeführt wird, wird diese Lösung in linearer Zeit ausgeführt. Diese Lösung erfordert jedoch aufgrund derstd::unordered_set
Datenstruktur zusätzlichen linearen Raum .
Trotzdem suche ich nach einer Lösung, die in linearer Zeit läuft und keinen zusätzlichen linearen Raum benötigt. Irgendwelche Ideen? Es scheint, dass ich gezwungen bin, Geschwindigkeit gegen Weltraum zu tauschen.
Nun, da wir bereits ein sortiertes Array erhalten, können wir dies mit zwei Zeigern tun. Wir behalten zuerst einen linken Zeiger am Anfang des Arrays und einen rechten Zeiger am Ende des Arrays und prüfen dann in jeder Iteration, ob die Summe des Wertes von linker Zeigerindex und Wert des rechten Zeigerindex sind gleich oder nicht, wenn ja, kehren Sie von hier zurück, andernfalls müssen wir entscheiden, wie die Grenze verringert werden soll, dh entweder den linken Zeiger erhöhen oder den rechten Zeiger verringern, also vergleichen wir die temporäre Summe mit gegebene Summe und wenn diese temporäre Summe größer als die gegebene Summe ist, dann entscheiden wir uns, den rechten Zeiger zu reduzieren. Wenn wir den linken Zeiger erhöhen, bleibt die temporäre Summe gleich oder erhöht sich nur, aber niemals kleiner, also beschließen wir, den rechten Zeiger so zu reduzieren vorübergehende Summenabnahme und wir erreichen nahe unserer gegebenen Summe, ähnlich, wenn die vorübergehende Summe kleiner als die gegebene Summe ist,Daher bleibt keine Bedeutung des Reduzierens des rechten Zeigers als temporäre Summe entweder Summe oder verringert sich mehr, erhöht sich jedoch nie, sodass wir unseren linken Zeiger erhöhen, sodass sich unsere temporäre Summe erhöht und wir nahe an der angegebenen Summe erreichen, und wir führen den gleichen Vorgang immer wieder durch, es sei denn, wir Holen Sie sich die gleiche Summe oder der Wert des linken Zeigerindex wird größer als der rechte Zeigerindex des rechten Zeigers oder umgekehrt. Dies ist der Code zur Demonstration. Lassen Sie mich wissen, wenn etwas nicht klar istLassen Sie mich wissen, wenn etwas nicht klar istLassen Sie mich wissen, wenn etwas nicht klar ist
quelle