Menemukan tiga elemen dalam array yang jumlahnya paling dekat dengan angka yang diberikan

155

Diberikan array bilangan bulat, A 1 , A 2 , ..., A n , termasuk negatif dan positif, dan bilangan bulat lainnya S. Sekarang kita perlu menemukan tiga bilangan bulat yang berbeda dalam array, yang jumlahnya paling dekat dengan bilangan bulat S yang diberikan Jika ada lebih dari satu solusi, salah satunya tidak masalah.

Anda dapat mengasumsikan semua bilangan bulat berada dalam kisaran int32_t, dan tidak ada aritmatika overflow akan terjadi dengan menghitung jumlah. S tidak ada yang istimewa selain nomor yang dipilih secara acak.

Apakah ada algoritma yang efisien selain pencarian brute force untuk menemukan tiga bilangan bulat?

ZelluX
sumber
1
Jika Anda mencari jumlah yang sama dengan angka (dan bukan yang terdekat), ini akan menjadi masalah 3SUM .
Bernhard Barker

Jawaban:

186

Apakah ada algoritma yang efisien selain pencarian brute force untuk menemukan tiga bilangan bulat?

Ya; kita bisa menyelesaikan ini dalam waktu O (n 2 )! Pertama, pertimbangkan bahwa masalah Anda Pdapat diungkapkan dengan cara yang sedikit berbeda sehingga menghilangkan kebutuhan akan "nilai target":

masalah asli P: Mengingat sebuah array Adari ninteger dan nilai target S, apakah terdapat 3-tupel dari Ajumlah itu untuk S?

dimodifikasi masalah P': Mengingat sebuah array Adari nbilangan bulat, tidak terdapat 3-tupel dari Ajumlah yang ke nol?

Perhatikan bahwa Anda dapat pergi dari versi ini masalah P'dari Pdengan mengurangkan S Anda / 3 dari setiap elemen dalam A, tapi sekarang Anda tidak perlu nilai target lagi.

Jelas, jika kita hanya menguji semua 3-tupel yang mungkin, kita akan menyelesaikan masalah di O (n 3 ) - itulah garis dasar brute-force. Apakah mungkin berbuat lebih baik? Bagaimana jika kita memilih tuple dengan cara yang agak lebih pintar?

Pertama, kami menginvestasikan waktu untuk mengurutkan array, yang dikenakan biaya penalti awal O (n log n). Sekarang kita jalankan algoritma ini:

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.
}

Algoritma ini bekerja dengan menempatkan tiga pointer, i, j, dan kpada berbagai titik dalam array. idimulai dari awal dan perlahan-lahan bekerja sampai akhir. kmenunjuk ke elemen terakhir. jmenunjuk ke tempat idimulainya. Kami berulang mencoba untuk menjumlahkan elemen pada indeks masing-masing, dan setiap kali salah satu dari berikut terjadi:

  • Jumlahnya tepat! Kami telah menemukan jawabannya.
  • Jumlahnya terlalu kecil. Bergerak jlebih dekat ke ujung untuk memilih nomor terbesar berikutnya.
  • Jumlahnya terlalu besar. Bergerak klebih dekat ke awal untuk memilih nomor terkecil berikutnya.

Untuk masing-masing i, petunjuk dari jdan ksecara bertahap akan lebih dekat satu sama lain. Akhirnya mereka akan saling melewati, dan pada saat itu kita tidak perlu mencoba hal lain untuk itu i, karena kita akan menjumlahkan elemen yang sama, hanya dalam urutan yang berbeda. Setelah itu, kami mencoba yang berikutnya idan ulangi.

Akhirnya, kita akan menghabiskan kemungkinan yang berguna, atau kita akan menemukan solusinya. Anda dapat melihat bahwa ini adalah O (n 2 ) karena kami mengeksekusi loop luar O (n) kali dan kami mengeksekusi loop dalam O (n) kali. Dimungkinkan untuk melakukan ini secara sub-kuadrat jika Anda benar-benar suka, dengan mewakili setiap integer sebagai vektor bit dan melakukan transformasi Fourier cepat, tetapi itu di luar cakupan jawaban ini.


Catatan: Karena ini adalah pertanyaan wawancara, saya telah sedikit menipu: algoritma ini memungkinkan pemilihan elemen yang sama beberapa kali. Artinya, (-1, -1, 2) akan menjadi solusi yang valid, seperti halnya (0, 0, 0). Ia juga hanya menemukan jawaban yang tepat , bukan jawaban yang paling dekat, seperti judulnya. Sebagai latihan untuk pembaca, saya akan membiarkan Anda mencari tahu cara membuatnya bekerja dengan elemen yang berbeda saja (tapi itu perubahan yang sangat sederhana) dan jawaban yang tepat (yang juga merupakan perubahan yang sederhana).

John Feminella
sumber
8
Tampaknya algoritme hanya dapat menemukan 3-tupel yang sama dengan S, bukan yang terdekat dengan S.
ZelluX
7
ZelluX: Seperti yang saya sebutkan dalam catatan, saya tidak ingin memberikan terlalu banyak karena ini masalah wawancara. Semoga Anda bisa melihat cara memodifikasinya sehingga Anda mendapat jawaban terdekat. (Petunjuk: satu cara adalah melacak jawaban terdekat sejauh ini dan menimpanya jika Anda menemukan yang lebih baik.)
John Feminella
12
bagaimana jika kita tidak mengubah pernyataan masalah, alih-alih kita akan mencari aj dan ak jumlah itu ke ai + S.
Boolean
3
@ZelluX: Ini mirip dengan cara kerja semacam gabungan (itulah cara pertama kali diklik untuk saya). Apa yang loop batin sedang mencoba untuk lakukan adalah membuktikan bahwa baik A [j] atau A [k] tidak dapat menjadi bagian dari setiap solusi memuaskan. Masalahnya adalah: "Apakah ada pasangan j '> = j dan k' <= k sedemikian sehingga A [j] + A [k] = S - A [i]?" Melihat pasangan saat ini (i, j), ada 3 kemungkinan: penjumlahannya tepat (hentikan - kami menang!), Terlalu rendah, atau terlalu tinggi. Jika terlalu rendah, maka jumlah A [j] + A [k '] juga harus terlalu rendah untuk setiap k' <= k, karena dalam setiap jumlah tersebut istilah pertama (A [j]) akan sama. ..
j_random_hacker
1
... dan suku kedua (A [k ']) akan sama atau bahkan lebih rendah dari A [k]. Jadi dalam hal ini kami telah membuktikan bahwa A [j] tidak dapat berpartisipasi dalam setiap sum memuaskan - jadi kami mungkin juga membuangnya! Yang kami lakukan dengan menetapkan j = j +1 dan memulai dari awal (meskipun mungkin membantu untuk berpikir dalam memecahkan subproblem yang lebih kecil secara rekursif sebagai gantinya). Demikian juga jika jumlah A [j] + A [k] terlalu tinggi, maka kita tahu bahwa A [j '] + A [k] juga harus terlalu tinggi untuk setiap j'> = j, karena A [j '] minimal harus sebesar A [j] dan kita sudah terlalu tinggi. Ini berarti kita dapat dengan aman membuang A [k] dengan mengatur k = k-1 dan memulai dari awal.
j_random_hacker
28

tentu saja ini adalah solusi yang lebih baik karena lebih mudah dibaca dan karena itu kurang rentan terhadap kesalahan. Satu-satunya masalah adalah, kita perlu menambahkan beberapa baris kode untuk menghindari beberapa pilihan satu elemen.

Solusi O (n ^ 2) lainnya (dengan menggunakan hashset).

// 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
sumber
8
Kelemahannya adalah penyimpanan O (N), daripada melakukannya di tempat.
Charles Munger
6
Menggunakan hashset tidak ketat O (n ^ 2) karena set hash dapat merosot dalam kesempatan langka, menghasilkan waktu pencarian linear.
Ext3h
@ Charles - Juga solusi John membutuhkan ruang O (N), karena Anda mengubah array asli saat menyortir. Itu berarti penelepon mungkin perlu salinan defensif sebelum menggunakan fungsi.
gamliela
Saya pikir ada kesalahan dalam algoritma Anda. s2mungkin elemen yang sudah dipilih. Misalnya jika array adalah 0,1,2dan Kadalah 2, tidak boleh ada jawaban. Saya pikir algoritma Anda akan menampilkan 0,1,1yang jelas salah.
Yamcha
7

Solusi John Feminella memiliki bug.

Di garis depan

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

Kita perlu memeriksa apakah i, j, k semuanya berbeda. Sebaliknya, jika elemen target saya adalah 6dan jika array input saya berisi {3,2,1,7,9,0,-4,6}. Jika saya mencetak tuple yang berjumlah 6, maka saya juga akan mendapatkan 0,0,6sebagai output. Untuk menghindari ini, kita perlu memodifikasi kondisi dengan cara ini.

if ((A[i] + A[j] + A[k] == 0) && (i!=j) && (i!=k) && (j!=k)) return (A[i], A[j], A[k])
Rambo7
sumber
2
Solusi John Feminella hanya untuk menyajikan algoritma untuk menyelesaikan masalah, ia juga telah menetapkan bahwa solusinya tidak akan bekerja untuk kondisi angka yang berbeda dan Anda harus memodifikasi kode di atas sedikit yang ia tinggalkan untuk pembaca.
EmptyData
3
Sebenarnya, saya tidak akan pernah menjadi j karena Anda selalu memulainya di j = i + 1. Satu-satunya kondisi nyata yang harus Anda periksa adalah apakah j == k. Namun, dengan mengatur loop sementara ke j <k, Anda telah memecahkan masalah tanpa pernyataan panjang jika karena k akan selalu lebih besar dari j dan j selalu lebih besar dari i.
lorenzocastillo
2
Ini sepertinya bukan jawaban untuk pertanyaan itu, tetapi lebih sebagai komentar atas jawaban John Feminella.
Bernhard Barker
6

Bagaimana dengan sesuatu seperti ini, yaitu O (n ^ 2)

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.
        }
    }

Ini menemukan jika jumlah 3 elemen persis sama dengan nomor Anda. Jika Anda ingin yang terdekat, Anda dapat memodifikasinya untuk mengingat delta terkecil (perbedaan antara jumlah triplet Anda saat ini) dan pada akhirnya cetak triplet yang sesuai dengan delta terkecil.

codaddict
sumber
jika Anda ingin menemukan elemen k untuk mendapatkan jumlah berapa kompleksitasnya? Bagaimana Anda menangani ini?
coder_15
Dengan pendekatan ini, kompleksitas untuk elemen k adalah O (n ^ (k-1)) untuk k> = 2. Anda perlu menambahkan loop luar untuk setiap ringkasan tambahan.
Ext3h
5

Perhatikan bahwa kami memiliki array yang diurutkan. Solusi ini mirip dengan solusi John hanya untuk mencari jumlah dan tidak mengulangi elemen yang sama.

#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
sumber
Diperlukan untuk menghitung perbedaan absolut dari a[r] + a[l] + a[i] - sum. Cobalah arr = [-1, 2, 1, -4] sum = 1.
Dimitry
3

Berikut adalah kode C ++:

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
sumber
2

Solusi N ^ 2 * logN yang sangat sederhana: urutkan array input, lalu lewati semua pasangan A i , A j (N ^ 2 kali), dan untuk setiap pasangan periksa apakah (S - A i - A j ) dalam array ( waktu logN).

Solusi O (S * N) lainnya menggunakan pendekatan pemrograman dinamis klasik .

Pendeknya:

Buat array 2-d V [4] [S + 1]. Isi sedemikian rupa, sehingga:

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

V 1 [A i ] = 1 untuk semua i, V 1 [x] = 0 untuk semua x lainnya

V [2] [A i + A j ] = 1, untuk setiap i, j. V [2] [x] = 0 untuk semua x lainnya

V [3] [jumlah dari 3 elemen] = 1.

Untuk mengisinya, lakukan iterate melalui A i , untuk setiap A i iterate melalui array dari kanan ke kiri.

Olexiy
sumber
sedikit perubahan pada algoritma pertama .. jika elemen tidak ada, maka pada akhir pencarian biner, kita harus melihat elemen di sebelah kiri, saat ini, dan kanan untuk melihat mana yang memberikan hasil terdekat .
Anurag
Array terlalu besar dan bukan O (s * N). Langkah ini adalah O (N ^ 2): V [2] [Ai + Aj] = 1, untuk i, j. V [2] [x] = 0 untuk semua x lainnya.
Richard
1

Ini dapat diselesaikan secara efisien dalam O (n log (n)) sebagai berikut. Saya memberikan solusi yang memberi tahu jika jumlah dari tiga angka sama dengan angka yang diberikan.

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
sumber
Saya tidak berpikir ini akan berhasil. Memang, Anda memiliki dua kasus sederhana tentang cara memajukan leftIndexatau rightIndexketika semua elemen di tengah benar-benar lebih kecil atau lebih besar dari jumlah yang Anda inginkan. Tapi bagaimana dengan kasus ketika pencarian biner berhenti di suatu tempat di tengah? Anda perlu memeriksa kedua cabang (di mana rightIndex--dan leftIndex++). Dalam solusi Anda, Anda mengabaikan situasi ini. Tetapi saya tidak berpikir bahwa ada cara untuk mengatasi masalah ini.
Aivean
0

Pengurangan: Saya pikir solusi @John Feminella O (n2) paling elegan. Kita masih bisa mengurangi A [n] untuk mencari tuple. Dengan mengamati A [k] sedemikian rupa sehingga semua elemen akan berada dalam A [0] - A [k], ketika array pencarian kami sangat besar dan SUM (s) sangat kecil.

A [0] minimum: - Array terurut naik.

s = 2A [0] + A [k]: Diberikan s dan A [] kita dapat menemukan A [k] menggunakan pencarian biner dalam log (n) waktu.

d1val
sumber
0

Berikut ini adalah program dalam java yang O (N ^ 2)

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
sumber
Pendekatan yang bagus, tapi saya tidak bisa mendapatkan titik di mana Anda membatasi jumlah hasil menjadi triplet. Sebagai contoh, pertimbangkan input: [1,11,3,4,5,6,7,8, 2] dan jumlah 12, dari solusi Anda tampak bahwa [1, 11] [4,8] [1,4, 5,2] dll semua akan berfungsi.
Anupam Saini
0

Masalahnya dapat diselesaikan dalam O (n ^ 2) dengan memperluas masalah 2-sum dengan modifikasi kecil. A adalah vektor yang mengandung elemen dan B adalah jumlah yang diperlukan.

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
sumber
0

Berikut adalah kode Python3

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
sumber
-1

Solusi lain yang memeriksa dan gagal lebih awal:

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;
    }

Saya menambahkan beberapa tes unit di sini: GivenArrayReturnTrueIfThreeElementsSumZeroTest .

Jika set menggunakan terlalu banyak ruang yang saya dapat dengan mudah menggunakan java.util.BitSet yang akan menggunakan O (n / w) ruang .

moxi
sumber
-1

Program untuk mendapatkan ketiga elemen tersebut. Saya baru saja mengurutkan array / daftar terlebih dahulu dan diperbarui minClosenessberdasarkan setiap triplet.

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
sumber
-2

Saya melakukan ini di n ^ 3, kodesemu saya di bawah ini;

// Buat hashMap dengan kunci sebagai Integer dan nilai sebagai ArrayList // iterate through list menggunakan for for, untuk setiap nilai dalam daftar iterate lagi mulai dari nilai berikutnya;

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

// jika jumlah arr [i] dan arr [j] kurang dari jumlah yang diinginkan maka ada potensi untuk menemukan digit ketiga jadi lakukan lagi untuk loop

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

// dalam hal ini kita sekarang mencari nilai ketiga; jika jumlah arr [i] dan arr [j] dan arr [k] adalah jumlah yang diinginkan kemudian tambahkan ini ke HashMap dengan membuat arr [i] kunci dan kemudian menambahkan arr [j] dan arr [k] ke dalam ArrayList dalam nilai kunci itu

          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]);}

setelah ini, Anda sekarang memiliki kamus yang memiliki semua entri yang mewakili tiga nilai yang ditambahkan ke jumlah yang diinginkan. Ekstrak semua entri ini menggunakan fungsi HashMap. Ini bekerja dengan sempurna.

di bawah titik beku
sumber