Trouver toutes les paires de nombres dans un tableau qui s’additionne à une somme donnée

Trouver toutes les paires de nombres dans un tableau qui s'additionnent à une somme donnée

1. Vue d'ensemble

Dans ce rapide didacticiel, nous allons montrer comment implémenter un algorithme pour rechercher toutes les paires de nombres dans un tableau dont la somme est égale à un nombre donné. Nous allons nous concentrer surtwo approaches to the problem.

Dans la première approche, nous trouverons toutes ces paires indépendamment de leur caractère unique. Dans le second, nous ne trouverons que les combinaisons de nombres uniques, en supprimant les paires redondantes.

Pour chaque approche, nous présenterons deux implémentations: une implémentation traditionnelle utilisantfor loops, et une seconde utilisant l'API Java 8 Stream.

2. Renvoyer toutes les paires correspondantes

Nous allons parcourir un tableau d'entiers, en trouvant toutes les paires (i etj) qui totalisent le nombre donné (sum) en utilisant une approche en boucle imbriquée par force brute . This algorithm will have a runtime complexity of O(n2).

Pour nos démonstrations, nous rechercherons toutes les paires de nombres dont la somme est égale à6, en utilisant le tableauinput suivant:

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

Dans cette approche, notre algorithme devrait renvoyer:

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

Dans chacun des algorithmes, lorsque nous trouvons une paire cible de nombres qui totalisent le nombre cible, nous collectons la paire en utilisant une méthode utilitaire,addPairs(i, j).

La première façon dont nous pourrions penser pour implémenter la solution est d'utiliser la boucle traditionnellefor:

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

Cela peut être un peu rudimentaire, donclet’s also write an implementation using the Java 8 Stream API.

Ici, nous utilisons la méthodeIntStream.range pour générer un flux séquentiel de nombres. Ensuite, nous les filtrons pour notre condition: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. Renvoyer toutes les paires correspondantes uniques

Pour cet exemple, nous devronsdevelop a smarter algorithm that returns only the unique number combinations, omitting redundant pairs.

Pour ce faire, nous allons ajouter chaque élément à une carte de hachage (sans tri), en vérifiant d'abord si la paire a déjà été affichée. Sinon, nous allons le récupérer et le marquer comme indiqué (définir le champvalue commenull).

En conséquence, en utilisant le même tableauinput qu'avant, et une somme cible de6, notre algorithme ne devrait renvoyer que les différentes combinaisons de nombres:

{2,4}, {3,3}

Si nous utilisons un sloop traditionnelfor , nous aurons:

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

Notez que cette implémentation améliore la complexité précédente, commewe use only one for loop, so we’ll have O(n).

Résolvons maintenant le problème à l'aide de Java 8 et de l'API Stream:

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

Dans cet article, nous avons expliqué différentes manières de rechercher toutes les paires qui résument un nombre donné en Java. Nous avons vu deux solutions différentes, chacune utilisant deux méthodes de base Java.

Comme d'habitude, tous les exemples de code présentés dans cet article peuvent êtrefound on GitHub - il s'agit d'un projet Maven, il devrait donc être facile de le compiler et de l'exécuter.