与えられた合計になる配列内のすべての数字の組を見つける

指定された合計になる配列内のすべての数値のペアを見つける

1. 概要

このクイックチュートリアルでは、合計が指定された数値に等しい配列内の数値のすべてのペアを見つけるためのアルゴリズムを実装する方法を示します。 two approaches to the problemに焦点を当てます。

最初のアプローチでは、一意性に関係なく、そのようなペアをすべて見つけます。 2つ目では、一意の番号の組み合わせのみを検索し、冗長なペアを削除します。

それぞれのアプローチについて、2つの実装を紹介します。1つはfor loopsを使用する従来の実装で、もう1つはJava 8 StreamAPIを使用する実装です。

2. 一致するすべてのペアを返す

整数の配列を反復処理し、ブルートフォースのネストされたループアプローチを使用して、指定された数(sum)に合計されるすべてのペア(ij)を見つけます。 This algorithm will have a runtime complexity of O(n2).

デモンストレーションでは、次のinput配列を使用して、合計が6に等しいすべての数値のペアを探します。

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

このアプローチでは、アルゴリズムは以下を返します。

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

各アルゴリズムで、合計がターゲット数になるターゲットペアの数値が見つかったら、ユーティリティメソッドaddPairs(i, j)を使用してペアを収集します。

ソリューションの実装を考える最初の方法は、従来の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]));
        }
    }
}

これは少し初歩的なものになる可能性があるため、let’s also write an implementation using the Java 8 Stream APIです。

ここでは、メソッドIntStream.range を使用して、数値の連続ストリームを生成します。 次に、条件でそれらをフィルタリングします: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. すべての一意の一致するペアを返します

この例では、develop a smarter algorithm that returns only the unique number combinations, omitting redundant pairsにする必要があります。

これを実現するために、すべての要素を(並べ替えなしで)ハッシュマップに追加し、最初にペアがすでに表示されているかどうかを確認します。 そうでない場合は、表示されているように取得してマークを付けます(valueフィールドをnullとして設定します)。

したがって、以前と同じinput配列、および6のターゲット合計を使用して、アルゴリズムは異なる数値の組み合わせのみを返す必要があります。

{2,4}, {3,3}

従来のfor スループを使用すると、次のようになります。

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

この実装は、we use only one for loop, so we’ll have O(n)として、以前の複雑さを改善することに注意してください。

それでは、Java8とStreamAPIを使用して問題を解決しましょう。

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. 結論

この記事では、Javaで特定の数を合計するすべてのペアを見つけるいくつかの異なる方法を説明しました。 それぞれ2つのJavaコアメソッドを使用する2つの異なるソリューションを見ました。

いつものように、この記事に示されているすべてのコードサンプルはfound on GitHubである可能性があります。これはMavenプロジェクトであるため、コンパイルと実行が簡単である必要があります。