JavaScriptで各インデックスの累積合計(累積和)を求める方法
JavaScriptで累積和を求めるには?
本記事では、数値の配列を受け取り、各インデックスに対して「そのインデックスまでの全要素の合計」を格納した新しい配列を返すJavaScript関数の作成方法を解説します。このような配列は一般に累積和(cumulative sum)と呼ばれます。
例:
入力配列が次の場合:
const arr = [1, 2, 3, 4, 5];
期待される出力は次のとおりです:
const output = [1, 3, 6, 10, 15];
ご覧のとおり、出力の各要素は「先頭からその位置までの合計」になっています(1 → 1+2=3 → 1+2+3=6 …)。
アプローチ:動的計画法の考え方を使う
この問題は、動的計画法(Dynamic Programming)の考え方を使うことで効率的に解けます。各反復処理で「直前の累積合計」を保持し、そこに現在の要素を加算するだけで新しい要素を生成できます。
もし毎回先頭から合計を計算し直すと二重ループが必要になり計算量は O(n²) になりますが、この手法なら前の結果を再利用できるため O(n) の時間計算量で済み、非常に高速です。
実装例
以下がコード全体です:
const arr = [1, 2, 3, 4, 5];
const cumulativeSum = arr => {
let result = [arr[0]];
for(let i = 1; i < arr.length; i++) {
result.push(arr[i] + result[i-1]);
}
return result;
}
console.log(cumulativeSum(arr));
出力結果
コンソールには以下が出力されます:
[ 1, 3, 6, 10, 15 ]
補足:reduce() を使ったより簡潔な書き方
Array.prototype.reduce() を活用すれば、同じ処理を関数型スタイルで一行に近い形で記述できます。
const arr = [1, 2, 3, 4, 5];
const cumulativeSum = arr =>
arr.reduce((acc, num, i) => {
acc.push(i === 0 ? num : acc[i - 1] + num);
return acc;
}, []);
console.log(cumulativeSum(arr)); // [ 1, 3, 6, 10, 15 ]
どちらの実装でも結果は同じですが、forループ版は処理の流れが直感的に分かりやすく、reduce() 版はコードが簡潔になるという特徴があります。用途やチームのコーディングスタイルに合わせて使い分けるとよいでしょう。
-
JavaScriptで配列を分割したときの平均値の合計の最大値を求める方法
問題の概要 数値の配列 arr を第一引数に、数値 num(num は arr の長さ以下)を第二引数に受け取るJavaScript関数を作成します。 この関数の目的は、配列 arr を最大 num 個の「隣接する空でないグループ」に分割することです。分割の際、どの要素も取り残してはいけません。 そして、考えられるすべての分割方法の中から、各グループの平均値の合計が最大になるような分割を選び出し、その最大の合計値を返します。 例として、次の入力を考えてみましょう。 入力 const arr = [10, 2, 3, 4, 10]; const num = 3; 出力 const output
-
【JavaScript】配列の中で左右の合計が等しくなる中央インデックス(ピボットインデックス)を見つける方法
問題数値の配列 arr が与えられたとき、「あるインデックスより左側にあるすべての要素の合計」と「そのインデックスより右側にあるすべての要素の合計」が等しくなる位置(中央インデックス/ピボットインデックス)を求める JavaScript 関数を作成します。該当するインデックスが複数存在する場合は、最初に見つかったものを返し、存在しない場合は -1 を返すのが一般的です。たとえば、次のような入力を考えます。入力const arr = [1, 7, 3, 6, 5, 6];出力const output = 3;出力の解説インデックス 3 の要素は nums[3] = 6 です。この要素の左側にある