JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

【JavaScript】特定の合計値になる一意の数値ペアを見つけ、そのインデックスの合計を求める方法

今回は、数値の配列を第1引数に、目標となる合計値(target sum)を第2引数にとる関数をJavaScriptで作成します。関数では配列をループ処理し、各要素どうし(自分自身との組み合わせは除く)の和を順番に計算していきます。

ループ中の2つの値の合計が目標値と一致し、かつそのペアがまだ出現していない場合は、該当する要素のインデックスを記憶します。最終的に、記憶したすべてのインデックスの合計値を返すのが目的です。

例として、配列が次のような場合を考えてみましょう。

const arr = [1, 4, 2, 3, 0, 5];

目標の合計値が次の場合です。

const sum = 7;

このとき、期待される出力は 11 になります。理由は以下のとおりです。

4 + 3 = 7
5 + 2 = 7

これらの値に対応するインデックスは次のようになっています。

4 [index: 1]
2 [index: 2]
3 [index: 3]
5 [index: 5]

つまり、これらのインデックスを合計すると −

1 + 2 + 3 + 5 = 11

実装コード

この処理を実装したコードが以下です。

const arr = [1, 4, 2, 3, 0, 5];

const findIndexSum = (arr = [], sum = 0) => {
    // 元の配列を変更しないようコピーを作成
    let copy = arr.slice(0);
    const used = [];
    let index = 0, indexFirst = 0, indexSecond, first, second;

    // 二重ループですべてのペアを調査
    while (indexFirst < copy.length){
        indexSecond = indexFirst + 1;
        while (indexSecond < copy.length){
            first = copy[indexFirst];
            second = copy[indexSecond];
            if (first + second === sum){
                // 条件を満たすペアを記録し、使用済み要素を除去
                used.push(first, second);
                copy = copy.filter(el => first !== el && second !== el);
                indexFirst--;
                break;
            }
            indexSecond++;
        }
        indexFirst++;
    };

    // 記録した値からインデックスを取得し、合計を求める
    const indexSum = used.sort((a, b) => a - b).reduce((acc, val, ind) => {
        const fromIndex = ind === 0 || val !== used[ind - 1] ? 0 : index + 1;
        index = arr.indexOf(val, fromIndex);
        return acc + index;
    }, 0);
    return indexSum;
};

console.log(findIndexSum(arr, 7));

出力結果

コンソールには次のように表示されます。

11

コードのポイント解説

この関数の処理の流れを整理すると、次のステップで構成されています。

  • 配列のコピー: slice() を使って元の配列のコピーを作成し、元データを保護します。
  • 二重ループによるペア探索: 外側と内側の2つのループを組み合わせ、同じ要素を重複して使わないようにしながら全ペアを調べます。
  • 条件判定と記録: 2つの値の合計が目標値と一致したら、その値を used 配列に記録し、filter() で使用済みの要素をコピーから取り除きます。これにより、同じペアが二重にカウントされることを防ぎます。
  • インデックスの合計計算: 最後に reduce() を使い、記録された各値について indexOf() で元の配列上のインデックスを取得し、その合計を算出します。同一の値が複数回現れるケースにも対応できるよう、検索開始位置を管理しています。

なお、この実装は二重ループを使用しているため、計算量は O(n²) となります。小規模な配列には十分ですが、大規模なデータセットではハッシュマップ(Mapオブジェクトなど)を活用した O(n) の最適化も検討するとよいでしょう。

  1. C++で配列内の一意なペア(ユニークペア)の数を求める方法をわかりやすく解説

    C++で配列内に存在する一意なペア(ユニークペア)の数を求めるには、適切な考え方と実装方法を理解しておく必要があります。一意なペアの数を数えるとは、与えられた配列から作成できるすべてのペアの中で、重複しないペアだけをカウントすることを意味します。例えば、次のようなケースが挙げられます。入力 : array[ ] = { 5, 5, 9 } 出力 : 4 説明 : 一意なペアは (5, 5)、(5, 9)、(9, 5)、(9, 9) の4つです。 入力 : array[ ] = { 5, 4, 3, 2, 2 } 出力 : 16解決のためのアプローチこの問題を解くには、主に2つのアプローチがあ

  2. Pythonで配列から1つの要素を削除して「良い配列」になるインデックスをすべて見つける方法

    問題の概要 数値の配列 A が与えられたとき、i 番目の要素を削除した後に「良い配列(good array)」となるような、すべてのインデックスを見つける必要があります。ここでの条件は以下の通りです。 良い配列とは、配列内のある要素が、それ以外のすべての要素の合計と等しい配列のことです。 インデックスは 1 始まり(1-based)で表します。 たとえば、入力が [10, 4, 6, 2] の場合、出力は [1, 4] になります。 A[1](=10)を削除すると、配列は [4, 6, 2] となり、6 = 4 + 2 が成立するため良い配列です。 A[4](=2)を削除すると、配列は