Finden von drei Elementen in einem Array, dessen Summe einer bestimmten Zahl am nächsten kommt

155

Bei einem gegebenen Array von ganzen Zahlen A 1 , A 2 , ..., A n , einschließlich Negativen und Positiven, und einer weiteren ganzen Zahl S. Nun müssen wir drei verschiedene ganze Zahlen im Array finden, deren Summe der gegebenen ganzen Zahl S am nächsten kommt Wenn es mehr als eine Lösung gibt, ist eine davon in Ordnung.

Sie können davon ausgehen, dass alle Ganzzahlen im Bereich int32_t liegen und bei der Berechnung der Summe kein arithmetischer Überlauf auftritt. S ist nichts Besonderes als eine zufällig ausgewählte Zahl.

Gibt es einen anderen effizienten Algorithmus als die Brute-Force-Suche, um die drei ganzen Zahlen zu finden?

ZelluX
quelle
1
Wenn Sie nach einer Summe suchen, die einer Zahl entspricht (und nicht der nächsten entspricht), ist dies das 3SUM-Problem .
Bernhard Barker

Antworten:

186

Gibt es einen anderen effizienten Algorithmus als die Brute-Force-Suche, um die drei ganzen Zahlen zu finden?

Ja; wir können dies in O (n 2 ) Zeit lösen ! Bedenken Sie zunächst, dass Ihr Problem Pauf eine etwas andere Weise äquivalent formuliert werden kann, sodass kein "Zielwert" erforderlich ist:

ursprüngliches Problem P: Gibt es bei einem Array Avon nganzen Zahlen und einem Zielwert Sein 3-Tupel von Adiesen Summen bis S?

modifiziertes Problem P': Gibt es bei einem Array Avon nganzen Zahlen ein 3-Tupel von Adieser Summe bis Null?

Beachten Sie, dass Sie von dieser Version des Problems gehen kann P'von der Pdurch Subtrahieren Ihre S / 3 von jedem Element in A, aber jetzt müssen Sie nicht den Zielwert mehr benötigen.

Wenn wir einfach alle möglichen 3-Tupel testen, lösen wir das Problem in O (n 3 ) - das ist die Brute-Force-Basislinie. Kann man es besser machen? Was ist, wenn wir die Tupel etwas intelligenter auswählen?

Zuerst investieren wir etwas Zeit, um das Array zu sortieren, was uns eine anfängliche Strafe von O (n log n) kostet. Nun führen wir diesen Algorithmus aus:

for (i in 1..n-2) {
  j = i+1  // Start right after i.
  k = n    // Start at the end of the array.

  while (k >= j) {
    // We got a match! All done.
    if (A[i] + A[j] + A[k] == 0) return (A[i], A[j], A[k])

    // We didn't match. Let's try to get a little closer:
    //   If the sum was too big, decrement k.
    //   If the sum was too small, increment j.
    (A[i] + A[j] + A[k] > 0) ? k-- : j++
  }
  // When the while-loop finishes, j and k have passed each other and there's
  // no more useful combinations that we can try with this i.
}

Dieser Algorithmus funktioniert durch drei Zeiger platzieren, i, j, und kan verschiedenen Stellen in der Anordnung. ibeginnt am Anfang und arbeitet sich langsam bis zum Ende vor. kzeigt auf das allerletzte Element. jzeigt darauf, wo ibei begonnen hat. Wir versuchen iterativ, die Elemente an ihren jeweiligen Indizes zu summieren, und jedes Mal passiert eines der folgenden Ereignisse:

  • Die Summe ist genau richtig! Wir haben die Antwort gefunden.
  • Die Summe war zu klein. Gehen Sie jnäher an das Ende heran, um die nächstgrößere Zahl auszuwählen.
  • Die Summe war zu groß. Gehen Sie knäher an den Anfang, um die nächstkleinere Zahl auszuwählen.

Für jeden inähern sich die Zeiger von jund kallmählich an. Irgendwann werden sie sich überholen, und an diesem Punkt müssen wir nichts anderes dafür versuchen i, da wir die gleichen Elemente nur in einer anderen Reihenfolge summieren würden. Nach diesem Punkt versuchen wir den nächsten iund wiederholen.

Schließlich werden wir entweder die nützlichen Möglichkeiten ausschöpfen oder die Lösung finden. Sie können sehen, dass dies O (n 2 ) ist, da wir die äußere Schleife O (n) mal ausführen und die innere Schleife O (n) mal ausführen. Es ist möglich, dies subquadratisch zu tun, wenn Sie wirklich Lust haben, indem Sie jede ganze Zahl als Bitvektor darstellen und eine schnelle Fourier-Transformation durchführen, aber das geht über den Rahmen dieser Antwort hinaus.


Hinweis: Da es sich um eine Interviewfrage handelt, habe ich hier ein wenig geschummelt: Dieser Algorithmus ermöglicht die mehrfache Auswahl desselben Elements. Das heißt, (-1, -1, 2) wäre eine gültige Lösung, ebenso wie (0, 0, 0). Es werden auch nur die genauen Antworten gefunden, nicht die nächstgelegene Antwort, wie im Titel erwähnt. Als Übung für den Leser werde ich Sie herausfinden lassen, wie es nur mit bestimmten Elementen (aber es ist eine sehr einfache Änderung) und genauen Antworten (was auch eine einfache Änderung ist) funktioniert.

John Feminella
quelle
8
Es scheint, dass der Algorithmus nur 3-Tupel finden kann, die gleich S sind, nicht am nächsten an S.
ZelluX
7
ZelluX: Wie ich in der Notiz erwähnt habe, wollte ich nicht zu viel verraten, da es sich um ein Interviewproblem handelt. Hoffentlich können Sie sehen, wie Sie es ändern können, damit Sie die bestmögliche Antwort erhalten. (Hinweis: Eine Möglichkeit besteht darin, die bisher nächstgelegene Antwort im Auge zu behalten und sie zu überschreiben, wenn Sie eine bessere finden.)
John Feminella
12
Was ist, wenn wir die Problemstellung nicht ändern, sondern nach aj suchen und diese Summe zu ai + S ak.
Boolean
3
@ZelluX: Es ist ähnlich wie bei einer Zusammenführungssortierung (so hat es zuerst für mich geklickt). Diese innere Schleife versucht zu beweisen, dass entweder A [j] oder A [k] nicht Teil einer zufriedenstellenden Lösung sein können. Das Problem ist zu jedem Zeitpunkt: "Gibt es ein Paar j '> = j und k' <= k, so dass A [j] + A [k] = S - A [i]?" Wenn man sich das aktuelle Paar (i, j) ansieht, gibt es drei Möglichkeiten: Die Summe ist hoch (Stopp - wir haben gewonnen!), Sie ist zu niedrig oder zu hoch. Wenn es zu niedrig ist, muss auch die Summe A [j] + A [k '] für jedes k' <= k zu niedrig sein , da in jeder solchen Summe der erste Term (A [j]) gleich ist. ..
j_random_hacker
1
... und der zweite Term (A [k ']) ist gleich oder sogar niedriger als A [k]. In diesem Fall haben wir also bewiesen, dass A [j] nicht an einer zufriedenstellenden Summe teilnehmen kann - also können wir sie auch verwerfen! Was wir tun, indem wir j = j + 1 setzen und von vorne beginnen (obwohl es hilfreich sein kann, stattdessen rekursiv ein kleineres Teilproblem zu lösen). Wenn die Summe A [j] + A [k] zu hoch ist, dann wissen wir auch, dass A [j '] + A [k] für jedes j'> = j zu hoch sein muss , da A [j '] muss mindestens so groß wie A [j] sein und wir sind schon zu hoch. Dies bedeutet, dass wir A [k] sicher verwerfen können, indem wir k = k-1 setzen und von vorne beginnen.
j_random_hacker
28

Dies ist sicherlich eine bessere Lösung, da es leichter zu lesen und daher weniger fehleranfällig ist. Das einzige Problem ist, dass wir einige Codezeilen hinzufügen müssen, um die Mehrfachauswahl eines Elements zu vermeiden.

Eine weitere O (n ^ 2) -Lösung (unter Verwendung eines Hash-Sets).

// K is the sum that we are looking for
for i 1..n
    int s1 = K - A[i]
    for j 1..i
        int s2 = s1 - A[j]
        if (set.contains(s2))
            print the numbers
    set.add(A[i])
Cem
quelle
8
Nachteil ist der O (N) -Speicher, anstatt ihn direkt durchzuführen.
Charles Munger
6
Die Verwendung eines Hash-Sets ist kein striktes O (n ^ 2), da das Hash-Set in seltenen Fällen degenerieren kann, was zu bis zu linearen Suchzeiten führt.
Ext3h
@Charles - Auch die Lösung von John benötigt O (N) Speicherplatz, da Sie das ursprüngliche Array beim Sortieren ändern. Das bedeutet, dass der Anrufer möglicherweise eine defensive Kopie benötigt, bevor er die Funktion verwendet.
Gamliela
Ich denke, es gibt einen Fehler in Ihrem Algorithmus. s2könnte ein bereits ausgewähltes Element sein. Wenn das Array beispielsweise ist 0,1,2und Kist 2, sollte es keine Antwort geben. Ich denke, Ihr Algorithmus wird ausgegeben, 0,1,1was offensichtlich falsch ist.
Yamcha
7

John Feminellas Lösung hat einen Fehler.

An der Linie

if (A[i] + A[j] + A[k] == 0) return (A[i], A[j], A[k])

Wir müssen prüfen, ob i, j, k alle verschieden sind. Andernfalls, wenn mein Zielelement ist 6und wenn mein Eingabearray enthält {3,2,1,7,9,0,-4,6}. Wenn ich die Tupel ausdrucke, die sich zu 6 summieren, würde ich auch 0,0,6als Ausgabe erhalten. Um dies zu vermeiden, müssen wir die Bedingung auf diese Weise ändern.

if ((A[i] + A[j] + A[k] == 0) && (i!=j) && (i!=k) && (j!=k)) return (A[i], A[j], A[k])
Rambo7
quelle
2
Die Lösung von John Feminella besteht nur darin, einen Algorithmus zur Lösung des Problems vorzustellen. Er hat außerdem angegeben, dass seine Lösung für eine bestimmte Zahlenbedingung nicht funktionieren würde, und Sie müssen den obigen Code ein wenig ändern, den er dem Leser überlassen hat.
EmptyData
3
Eigentlich werde ich niemals j sein, da Sie es immer bei j = i + 1 beginnen. Die einzige reale Bedingung, die Sie überprüfen sollten, ist, ob j == k ist. Indem Sie jedoch die while-Schleife auf j <k setzen, haben Sie die Probleme ohne eine lange if-Anweisung gelöst, da k immer größer als j und j immer größer als i ist.
Lorenzocastillo
2
Dies scheint keine Antwort auf die Frage zu sein, sondern eher ein Kommentar zu John Feminellas Antwort.
Bernhard Barker
6

Wie wäre es mit so etwas, das O (n ^ 2) ist?

for(each ele in the sorted array)
{
    ele = arr[i] - YOUR_NUMBER;
    let front be the pointer to the front of the array;
    let rear be the pointer to the rear element of the array.;

    // till front is not greater than rear.                    
    while(front <= rear)
    {
        if(*front + *rear == ele)
        {
            print "Found triplet "<<*front<<","<<*rear<<","<<ele<<endl;
            break;
        }
        else
        {
            // sum is > ele, so we need to decrease the sum by decrementing rear pointer.
            if((*front + *rear) > ele)
                decrement rear pointer.
            // sum is < ele, so we need to increase the sum by incrementing the front pointer.
            else
                increment front pointer.
        }
    }

Dies stellt fest, ob die Summe von 3 Elementen genau Ihrer Zahl entspricht. Wenn Sie am nächsten kommen möchten, können Sie es so ändern, dass es sich an das kleinste Delta erinnert (Differenz zwischen der Anzahl der aktuellen Tripletts) und am Ende das Triplett druckt, das dem kleinsten Delta entspricht.

Codaddict
quelle
Wenn Sie k Elemente finden möchten, um die Summe zu erhalten, wie komplex ist sie dann? Wie gehst du damit um?
coder_15
Bei diesem Ansatz beträgt die Komplexität für k Elemente O (n ^ (k-1)) für k> = 2. Sie müssen für jeden zusätzlichen Summanden eine äußere Schleife hinzufügen.
Ext3h
5

Beachten Sie, dass wir ein sortiertes Array haben. Diese Lösung ähnelt Johns Lösung nur darin, dass sie nach der Summe sucht und nicht dasselbe Element wiederholt.

#include <stdio.h>;

int checkForSum (int arr[], int len, int sum) { //arr is sorted
    int i;
    for (i = 0; i < len ; i++) {
        int left = i + 1;
        int right = len - 1;
        while (right > left) {
            printf ("values are %d %d %d\n", arr[i], arr[left], arr[right]);
            if (arr[right] + arr[left] + arr[i] - sum == 0) {
                printf ("final values are %d %d %d\n", arr[i], arr[left], arr[right]);
                return 1;
            }
            if (arr[right] + arr[left] + arr[i] - sum > 0)
                right--;
            else
                left++;
        }
    }
    return -1;
}
int main (int argc, char **argv) {
    int arr[] = {-99, -45, -6, -5, 0, 9, 12, 16, 21, 29};
    int sum = 4;
    printf ("check for sum %d in arr is %d\n", sum, checkForSum(arr, 10, sum));
}
Pasada
quelle
Es wird benötigt, um die absolute Differenz von zu berechnen a[r] + a[l] + a[i] - sum. Anprobieren arr = [-1, 2, 1, -4] sum = 1.
Dimitry
3

Hier ist der C ++ - Code:

bool FindSumZero(int a[], int n, int& x, int& y, int& z)
{
    if (n < 3)
        return false;

    sort(a, a+n);

    for (int i = 0; i < n-2; ++i)
    {
        int j = i+1;
        int k = n-1;

        while (k >= j)
        {
            int s = a[i]+a[j]+a[k];

            if (s == 0 && i != j && j != k && k != i)
            {
                x = a[i], y = a[j], z = a[k];
                return true;
            }

            if (s > 0)
                --k;
            else
                ++j;
        }
    }

    return false;
}
Peter Lee
quelle
2

Sehr einfache N ^ 2 * logN-Lösung: Sortieren Sie das Eingabearray, gehen Sie dann alle Paare A i , A j (N ^ 2-mal) durch und prüfen Sie für jedes Paar, ob (S - A i - A j ) im Array ist ( logN Zeit).

Eine andere O (S * N) -Lösung verwendet den klassischen Ansatz der dynamischen Programmierung .

Zusamenfassend:

Erstellen Sie ein 2D-Array V [4] [S + 1]. Füllen Sie es so aus, dass:

V [0] [0] = 1, V [0] [x] = 0;

V 1 [A i ] = 1 für jedes i, V 1 [x] = 0 für alle anderen x

V [2] [A i + A j ] = 1 für jedes i, j. V [2] [x] = 0 für alle anderen x

V [3] [Summe von 3 beliebigen Elementen] = 1.

Um es zu füllen, durchlaufen Sie A i , für jedes A i durchlaufen Sie das Array von rechts nach links.

Olexiy
quelle
geringfügige Änderung des ersten Algorithmus. Wenn das Element nicht vorhanden ist, müssen wir am Ende der binären Suche das Element links, aktuell und rechts betrachten, um zu sehen, welches das nächstgelegene Ergebnis liefert .
Anurag
Das Array ist zu groß und nicht O (s * N). Dieser Schritt ist O (N ^ 2): V [2] [Ai + Aj] = 1 für jedes i, j. V [2] [x] = 0 für alle anderen x.
Richard
1

Dies kann in O (n log (n)) wie folgt effizient gelöst werden. Ich gebe eine Lösung, die sagt, ob die Summe von drei Zahlen einer gegebenen Zahl entspricht.

import java.util.*;
public class MainClass {
        public static void main(String[] args) {
        int[] a = {-1, 0, 1, 2, 3, 5, -4, 6};
        System.out.println(((Object) isThreeSumEqualsTarget(a, 11)).toString());
}

public static boolean isThreeSumEqualsTarget(int[] array, int targetNumber) {

    //O(n log (n))
    Arrays.sort(array);
    System.out.println(Arrays.toString(array));

    int leftIndex = 0;
    int rightIndex = array.length - 1;

    //O(n)
    while (leftIndex + 1 < rightIndex - 1) {
        //take sum of two corners
        int sum = array[leftIndex] + array[rightIndex];
        //find if the number matches exactly. Or get the closest match.
        //here i am not storing closest matches. You can do it for yourself.
        //O(log (n)) complexity
        int binarySearchClosestIndex = binarySearch(leftIndex + 1, rightIndex - 1, targetNumber - sum, array);
        //if exact match is found, we already got the answer
        if (-1 == binarySearchClosestIndex) {
            System.out.println(("combo is " + array[leftIndex] + ", " + array[rightIndex] + ", " + (targetNumber - sum)));
            return true;
        }
        //if exact match is not found, we have to decide which pointer, left or right to move inwards
        //we are here means , either we are on left end or on right end
        else {

            //we ended up searching towards start of array,i.e. we need a lesser sum , lets move inwards from right
            //we need to have a lower sum, lets decrease right index
            if (binarySearchClosestIndex == leftIndex + 1) {
                rightIndex--;
            } else if (binarySearchClosestIndex == rightIndex - 1) {
                //we need to have a higher sum, lets decrease right index
                leftIndex++;
            }
        }
    }
    return false;
}

public static int binarySearch(int start, int end, int elem, int[] array) {
    int mid = 0;
    while (start <= end) {
        mid = (start + end) >>> 1;
        if (elem < array[mid]) {
            end = mid - 1;
        } else if (elem > array[mid]) {
            start = mid + 1;
        } else {
            //exact match case
            //Suits more for this particular case to return -1
            return -1;
        }
    }
    return mid;
}
}
Raju Singh
quelle
Ich glaube nicht, dass das funktionieren wird. Zugegeben, Sie haben zwei einfache Fälle, wie Sie vorankommen leftIndexoder rightIndexwenn alle Elemente in der Mitte entweder streng kleiner oder größer als Ihre gewünschte Anzahl sind. Aber was ist mit dem Fall, als die binäre Suche irgendwo in der Mitte aufhörte? Sie müssten beide Zweige überprüfen (wo rightIndex--und leftIndex++). In Ihrer Lösung ignorieren Sie diese Situation einfach. Ich glaube jedoch nicht, dass es einen Weg gibt, dieses Problem zu lösen.
Aivean
0

Reduktion: Ich finde die @ John Feminella-Lösung O (n2) am elegantesten. Wir können immer noch das A [n] reduzieren, in dem nach Tupel gesucht werden soll. Indem Sie A [k] so beobachten, dass alle Elemente in A [0] - A [k] sind, wenn unser Sucharray groß und die Summe (n) wirklich klein ist.

Ein [0] ist Minimum: - Aufsteigendes sortiertes Array.

s = 2A [0] + A [k]: Mit s und A [] können wir A [k] mithilfe der binären Suche in log (n) -Zeit finden.

d1val
quelle
0

Hier ist das Programm in Java, das O (N ^ 2) ist.

import java.util.Stack;


public class GetTripletPair {

    /** Set a value for target sum */
    public static final int TARGET_SUM = 32;

    private Stack<Integer> stack = new Stack<Integer>();

    /** Store the sum of current elements stored in stack */
    private int sumInStack = 0;
    private int count =0 ;


    public void populateSubset(int[] data, int fromIndex, int endIndex) {

        /*
        * Check if sum of elements stored in Stack is equal to the expected
        * target sum.
        * 
        * If so, call print method to print the candidate satisfied result.
        */
        if (sumInStack == TARGET_SUM) {
            print(stack);
        }

        for (int currentIndex = fromIndex; currentIndex < endIndex; currentIndex++) {

            if (sumInStack + data[currentIndex] <= TARGET_SUM) {
                ++count;
                stack.push(data[currentIndex]);
                sumInStack += data[currentIndex];

                /*
                * Make the currentIndex +1, and then use recursion to proceed
                * further.
                */
                populateSubset(data, currentIndex + 1, endIndex);
                --count;
                sumInStack -= (Integer) stack.pop();
            }else{
            return;
        }
        }
    }

    /**
    * Print satisfied result. i.e. 15 = 4+6+5
    */

    private void print(Stack<Integer> stack) {
        StringBuilder sb = new StringBuilder();
        sb.append(TARGET_SUM).append(" = ");
        for (Integer i : stack) {
            sb.append(i).append("+");
        }
        System.out.println(sb.deleteCharAt(sb.length() - 1).toString());
    }

    private static final int[] DATA = {4,13,14,15,17};

    public static void main(String[] args) {
        GetAllSubsetByStack get = new GetAllSubsetByStack();
        get.populateSubset(DATA, 0, DATA.length);
    }
}
M Sach
quelle
Netter Ansatz, aber ich konnte nicht den Punkt erreichen, an dem Sie die Anzahl der Ergebnisse auf ein Triplett beschränken. Betrachten Sie zum Beispiel die Eingabe: [1,11,3,4,5,6,7,8, 2] und Summe 12, aus Ihrer Lösung geht hervor, dass [1, 11] [4,8] [1,4, 5,2] usw. würde alles funktionieren.
Anupam Saini
0

Das Problem kann in O (n ^ 2) gelöst werden, indem das 2-Summen-Problem mit geringfügigen Modifikationen erweitert wird. A ist der Vektor, der Elemente enthält, und B ist die erforderliche Summe.

int Solution :: threeSumClosest (Vektor & A, int B) {

sort(A.begin(),A.end());

int k=0,i,j,closest,val;int diff=INT_MAX;

while(k<A.size()-2)
{
    i=k+1;
    j=A.size()-1;

    while(i<j)
    {
        val=A[i]+A[j]+A[k];
        if(val==B) return B;
        if(abs(B-val)<diff)
        {
            diff=abs(B-val);
            closest=val;
        }
        if(B>val)
        ++i;
        if(B<val) 
        --j;
    }
    ++k;

}
return closest;
Anurag Semwal
quelle
0

Hier ist der Python3-Code

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        result = set()
        nums.sort()
        L = len(nums)     
        for i in range(L):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            for j in range(i+1,L):
                if j > i + 1 and nums[j] == nums[j-1]:
                    continue  
                l = j+1
                r = L -1
                while l <= r:
                    sum = nums[i] + nums[j] + nums[l]
                    result.add(sum)
                    l = l + 1
                    while l<=r and nums[l] == nums[l-1]:
                        l = l + 1
        result = list(result)
        min = result[0]
        for i in range(1,len(result)):
            if abs(target - result[i]) < abs(target - min):
                min = result[i]
        return min
uday reddy
quelle
-1

Eine weitere Lösung, die frühzeitig überprüft und fehlschlägt:

public boolean solution(int[] input) {
        int length = input.length;

        if (length < 3) {
            return false;
        }

        // x + y + z = 0  => -z = x + y
        final Set<Integer> z = new HashSet<>(length);
        int zeroCounter = 0, sum; // if they're more than 3 zeros we're done

        for (int element : input) {
            if (element < 0) {
                z.add(element);
            }

            if (element == 0) {
                ++zeroCounter;
                if (zeroCounter >= 3) {
                    return true;
                }
            }
        }

        if (z.isEmpty() || z.size() == length || (z.size() + zeroCounter == length)) {
            return false;
        } else {
            for (int x = 0; x < length; ++x) {
                for (int y = x + 1; y < length; ++y) {
                    sum = input[x] + input[y]; // will use it as inverse addition
                    if (sum < 0) {
                        continue;
                    }
                    if (z.contains(sum * -1)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

Ich habe hier einige Komponententests hinzugefügt: GivenArrayReturnTrueIfThreeElementsSumZeroTest .

Wenn das Set zu viel Speicherplatz belegt, kann ich problemlos ein java.util.BitSet verwenden, das O (n / w) Speicherplatz verwendet .

Moxi
quelle
-1

Programm, um diese drei Elemente zu erhalten. Ich habe gerade zuerst das Array / die Liste sortiert und sie minClosenessbasierend auf jedem Triplett aktualisiert .

public int[] threeSumClosest(ArrayList<Integer> A, int B) {
    Collections.sort(A);
    int ansSum = 0;
    int ans[] = new int[3];
    int minCloseness = Integer.MAX_VALUE;
    for (int i = 0; i < A.size()-2; i++){
        int j = i+1;
        int k = A.size()-1;
        while (j < k){
            int sum = A.get(i) + A.get(j) + A.get(k);
            if (sum < B){
                j++;
            }else{
                k--;
            }
            if (minCloseness >  Math.abs(sum - B)){
                minCloseness = Math.abs(sum - B);
                ans[0] = A.get(i); ans[1] = A.get(j); ans[2] = A.get(k);
            }
        }
    }
    return ans;
}
Saurav Sahu
quelle
-2

Ich habe das in n ^ 3 gemacht, mein Pseudocode ist unten;

// Eine HashMap mit dem Schlüssel als Ganzzahl und dem Wert als ArrayList erstellen. // Die Liste mit einer for-Schleife durchlaufen, wobei jeder Wert in der Liste ab dem nächsten Wert erneut iteriert wird.

for (int i=0; i<=arr.length-1 ; i++){
    for (int j=i+1; j<=arr.length-1;j++){

// Wenn die Summe von arr [i] und arr [j] kleiner als die gewünschte Summe ist, besteht die Möglichkeit, eine dritte Ziffer zu finden, also machen Sie eine andere for-Schleife

      if (arr[i]+arr[j] < sum){
        for (int k= j+1; k<=arr.length-1;k++)

// In diesem Fall suchen wir jetzt nach dem dritten Wert. Wenn die Summe von arr [i] und arr [j] und arr [k] die gewünschte Summe ist, fügen Sie diese zur HashMap hinzu, indem Sie arr [i] zum Schlüssel machen und dann arr [j] und arr [k] hinzufügen die ArrayList im Wert dieses Schlüssels

          if (arr[i]+arr[j]+arr[k] ==  sum){              
              map.put(arr[i],new ArrayList<Integer>());
              map.get(arr[i]).add(arr[j]);
              map.get(arr[i]).add(arr[k]);}

Danach haben Sie jetzt ein Wörterbuch, in dem alle Einträge die drei Werte darstellen, die zur gewünschten Summe addiert werden. Extrahieren Sie alle diese Einträge mit HashMap-Funktionen. Das hat perfekt funktioniert.

unter Null
quelle