Finde alle Zahlenpaare in einem Array, die sich zu einer bestimmten Summe addieren

Finden Sie alle Zahlenpaare in einem Array, die sich zu einer bestimmten Summe addieren

1. Überblick

In diesem kurzen Tutorial zeigen wir, wie Sie einen Algorithmus zum Finden aller Zahlenpaare in einem Array implementieren, dessen Summe einer bestimmten Zahl entspricht. Wir konzentrieren uns auftwo approaches to the problem.

Im ersten Ansatz finden wir alle diese Paare unabhängig von ihrer Eindeutigkeit. Im zweiten Schritt finden wir nur die eindeutigen Zahlenkombinationen, wodurch redundante Paare entfernt werden.

Für jeden Ansatz werden zwei Implementierungen vorgestellt - eine herkömmliche Implementierung mitfor -Sloops und eine zweite mit der Java 8 Stream-API.

2. Alle übereinstimmenden Paare zurückgeben

Wir durchlaufen ein Array von Ganzzahlen und finden alle Paare (i undj), die sich mit einem Brute-Force-Nested-Loop-Ansatz zu der angegebenen Anzahl (sum) summieren . This algorithm will have a runtime complexity of O(n2).

Für unsere Demonstrationen suchen wir nach allen Zahlenpaaren, deren Summe6 entspricht, unter Verwendung des folgendeninput-Arrays:

int[] input = { 2, 4, 3, 3 };

Bei diesem Ansatz sollte unser Algorithmus Folgendes zurückgeben:

{2,4}, {4,2}, {3,3}, {3,3}

Wenn wir in jedem der Algorithmen ein Zielpaar von Zahlen finden, das sich zur Zielzahl summiert, erfassen wir das Paar mit der DienstprogrammmethodeaddPairs(i, j).

Der erste Weg, um die Lösung zu implementieren, ist die Verwendung der traditionellenfor-Schleife:

for (int i = 0; i < input.length; i++) {
    for (int j = 0; j < input.length; j++) {
        if (j != i && (input[i] + input[j]) == sum) {
            addPairs(input[i], sum-input[i]));
        }
    }
}

Dies kann etwas rudimentär sein, alsolet’s also write an implementation using the Java 8 Stream API.

Hier verwenden wir die MethodeIntStream.range , um einen sequentiellen Strom von Zahlen zu erzeugen. Dann filtern wir sie nach unserer Bedingung:number 1 + number 2 = sum:

IntStream.range(0,  input.length)
    .forEach(i -> IntStream.range(0,  input.length)
        .filter(j -> i != j && input[i] + input[j] == sum)
        .forEach(j -> addPairs(input[i], input[j]))
);

3. Geben Sie alle eindeutigen passenden Paare zurück

In diesem Beispiel müssen wirdevelop a smarter algorithm that returns only the unique number combinations, omitting redundant pairs eingeben.

Um dies zu erreichen, fügen wir jedes Element einer Hash-Map hinzu (ohne zu sortieren) und prüfen zunächst, ob das Paar bereits angezeigt wurde. Wenn nicht, rufen wir es ab und markieren es wie gezeigt (setzen Sie das Feldvaluealsnull).

Dementsprechend sollte unser Algorithmus unter Verwendung des gleicheninput-Arrays wie zuvor und einer Zielsumme von6 nur die verschiedenen Zahlenkombinationen zurückgeben:

{2,4}, {3,3}

Wenn wir eine traditionellefor -Sloop verwenden, haben wir:

Map pairs = new HashMap();
for (int i : input) {
    if (pairs.containsKey(i)) {
        if (pairs.get(i) != null) {
            addPairs(i, sum-i);
        }
        pairs.put(sum - i, null);
    } else if (!pairs.containsValue(i)) {
        pairs.put(sum-i, i);
    }
}

Beachten Sie, dass diese Implementierung die vorherige Komplexität alswe use only one for loop, so we’ll have O(n) verbessert.

Lösen wir nun das Problem mit Java 8 und der Stream-API:

Map pairs = new HashMap();
IntStream.range(0, input.length).forEach(i -> {
    if (pairs.containsKey(input[i])) {
        if (pairs.get(input[i]) != null) {
            addPairs(input[i], sum - input[i]);
        }
        pairs.put(sum - input[i], null);
    } else if (!pairs.containsValue(input[i])) {
        pairs.put(sum - input[i], input[i]);
    }
});

4. Fazit

In diesem Artikel haben wir verschiedene Möglichkeiten erläutert, um alle Paare zu finden, die eine bestimmte Zahl in Java zusammenfassen. Wir haben zwei verschiedene Lösungen gesehen, die jeweils zwei Java-Kernmethoden verwenden.

Wie üblich können alle in diesem Artikel gezeigten Codebeispielefound on GitHub sein - dies ist ein Maven-Projekt, daher sollte es einfach zu kompilieren und auszuführen sein.