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

【JavaScript】Two Sum(二数の和)問題をO(n)で解く効率的なアルゴリズム

この記事では、Two Sum(二数の和)問題を線形時間 O(n) 以内で解く関数の実装方法を解説します。

Two Sum問題とは

整数の配列が与えられたとき、その中から合計すると特定のターゲット値になる2つの数を見つけ出すのがTwo Sum問題です。

twoSum 関数は、合計がターゲットと一致する2つの数のインデックスを配列で返します。条件を満たす組み合わせが存在しない場合は、空の配列を返します。

O(n)で解くためのアプローチ

全てのペアを総当たりで調べる方法では計算量が O(n²) になってしまいます。そこで、ハッシュマップ(オブジェクト)を活用します。

具体的には、これまで走査した要素を「値 → インデックス」の形式でマップに記録していきます。各要素を処理する際、「ターゲットから現在の要素を引いた値(相方となる数)」がすでにマップに存在するかを確認します。存在すればそのインデックスと現在のインデックスを返し、ループを最後まで回しても見つからなければ空の配列を返します。こうすることで、配列を一度だけ走査すればよく、全体の計算量は O(n) に抑えられます。

コード例

const arr = [2, 5, 7, 8, 1, 3, 6, 9, 4];
const sum = 10;

const twoSum = (arr, sum) => {
    const map = {};
    for(let i = 0; i < arr.length; i++){
        // ターゲットから現在の要素を引いた値を求める
        const el = sum - arr[i];
        // 相方の数がすでにマップに存在すれば答え
        if(map[el]){
            return [map[el], i];
        }
        // 現在の要素をマップに記録
        map[arr[i]] = i;
    }
    return [];
};

console.log(twoSum(arr, sum));
console.log(twoSum(arr, 12));
console.log(twoSum(arr, 13));
console.log(twoSum(arr, 14));
console.log(twoSum(arr, 24));

出力結果

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

[ 2, 5 ]
[ 1, 2 ]
[ 1, 3 ]
[ 3, 6 ]
[]

このようにハッシュマップを使うことで、余分なネストしたループを排除しつつ、1回の走査でTwo Sum問題を効率よく解くことができます。

  1. JavaScriptでペアの最小値合計を最大化するアルゴリズムを解説

    この記事では、整数の配列を受け取り、ペアごとの最小値の合計が最大になるようにグループ分けするJavaScript関数の実装方法を解説します。 問題の概要 長さ2nの整数配列 arr を引数として受け取るJavaScript関数を作成します。この関数の目的は、配列内の整数をn個のペア (a1, b1), (a2, b2), ..., (an, bn) にグループ化し、各ペアの最小値 min(ai, bi) の合計(i = 1 から n まで)ができるだけ大きくなるようにすることです。 例えば、次の入力が与えられたとします。 const arr = [1, 4, 3, 2]; この場合、期待される

  2. JavaScriptで配列を分割したときの平均値の合計の最大値を求める方法

    問題の概要 数値の配列 arr を第一引数に、数値 num(num は arr の長さ以下)を第二引数に受け取るJavaScript関数を作成します。 この関数の目的は、配列 arr を最大 num 個の「隣接する空でないグループ」に分割することです。分割の際、どの要素も取り残してはいけません。 そして、考えられるすべての分割方法の中から、各グループの平均値の合計が最大になるような分割を選び出し、その最大の合計値を返します。 例として、次の入力を考えてみましょう。 入力 const arr = [10, 2, 3, 4, 10]; const num = 3; 出力 const output