Find All Pairs of Numbers in an Array That Add Up to a Given Sum in Java – 在Java中查找数组中加起来等于给定和的所有数字对

最后修改: 2018年 4月 23日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’ll show how to implement an algorithm for finding all pairs of numbers in an array whose sum equals a given number. We’ll focus on two approaches to the problem.

在这个快速教程中,我们将展示如何实现一种算法,以寻找数组中总和等于给定数字的所有数字对。我们将重点介绍解决该问题的两种方法

In the first approach, we’ll find all such pairs regardless of uniqueness. In the second, we’ll find only the unique number combinations, removing redundant pairs.

在第一种方法中,我们将找到所有这样的数字对,不管是否唯一。在第二种方法中,我们将只找到唯一的数字组合,去除多余的配对。

For each approach, we’ll present two implementations — a traditional implementation using for loops, and a second using the Java 8 Stream API.

对于每一种方法,我们将介绍两种实现方式–一种是使用for 循环的传统实现,另一种是使用Java 8 Stream API的实现。

2. Return All Matching Pairs

2.返回所有匹配的对子

We’ll iterate through an array of integers, finding all pairs (i and j) that sum up to the given number (sum) using a brute-force, nested-loop approach. This algorithm will have a runtime complexity of O(n2).

我们将遍历一个整数数组,使用粗暴的、嵌套的循环方法找到所有对(ij),其总和等于给定的数字(sum)。该算法的运行时间复杂度为O(n2)

For our demonstrations, we’ll look for all pairs of numbers whose sum is equal to 6, using the following input array:

在我们的演示中,我们将使用下面的input数组,寻找所有和等于6的数对。

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

In this approach, our algorithm should return:

在这种方法中,我们的算法应该返回。

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

In each of the algorithms, when we find a target pair of numbers that sum up to the target number, we’ll collect the pair using a utility method, addPairs(i, j).

在每一种算法中,当我们发现一对目标数字的总和为目标数字时,我们将使用一个实用方法收集这对数字,addPairs(i, j)

The first way we might think to implement the solution is by using the traditional for loop:

我们可能认为实现解决方案的第一种方式是使用传统的for循环:

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

This can be a bit rudimentary, so let’s also write an implementation using the Java 8 Stream API.

这可能有点简陋,所以让我们也用Java 8 Stream API写一个实现

Here, we use the method IntStream.range to generate a sequential stream of numbers. Then, we filter them for our condition: number 1 + number 2 = sum:

这里,我们使用IntStream.range方法来生成一个连续的数字流。然后,我们为我们的条件过滤它们:数字1+数字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. Return All Unique Matching Pairs

3.返回所有独特的匹配对

For this example, we’ll have to develop a smarter algorithm that returns only the unique number combinations, omitting redundant pairs.

对于这个例子,我们必须开发一个更聪明的算法,只返回唯一的数字组合,省略多余的配对

To achieve this, we’ll add every element to a hash map (without sorting), checking first if the pair has already been shown. If not, we’ll retrieve and mark it as shown (set value field as null).

为了实现这一目标,我们将把每个元素添加到哈希图中(不进行排序),首先检查该对元素是否已经被显示。如果没有,我们将检索并标记为已显示(将value字段设置为null)。

Accordingly, using the same input array as before, and a target sum of 6, our algorithm should return only the different number combinations:

因此,使用与之前相同的输入数组,并且目标和为6,我们的算法应该只返回不同的数字组合。

{2,4}, {3,3}

If we use a traditional for loop, we’ll have:

如果我们使用一个传统的for 循环,我们将有:

Map<Integer, Integer> 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);
    }
}

Note that this implementation improves on the previous complexity, as we use only one for loop, so we’ll have O(n).

请注意,这个实现比之前的复杂度有所提高,因为我们只使用一个for循环,所以我们会有O(n)

Now let’s solve the problem using Java 8 and the Stream API:

现在让我们用Java 8和Stream API来解决这个问题。

Map<Integer, Integer> 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

4.结论

In this article, we explained several different ways to find all pairs that sum up a given number in Java. We saw two different solutions, each using two Java core methods.

在这篇文章中,我们解释了在Java中寻找所有与给定数字相加的对的几种不同方法。我们看到了两种不同的解决方案,分别使用两种Java核心方法。

As usual, all the code samples shown in this article can be found on GitHub — this is a Maven project, so it should be easy to compile and run it.

像往常一样,本文展示的所有代码样本都可以在GitHub上找到–这是一个Maven项目,所以编译和运行它应该很容易。