JavaScriptで配列の合計を指定の数で割り切れるようにする、削除すべき最小の部分配列の求め方
本記事では、第一引数に正の整数の配列、第二引数に正の整数を受け取るJavaScript関数を実装します。この関数の目的は、元の配列から削除すべき最小の部分配列(連続する要素)の長さを求めて返すことです。削除後の残りの要素の合計が、第二引数で指定された数で割り切れる状態になる必要があります。
問題の例
たとえば、次のような入力が与えられたとします。
const arr = [3, 8, 2, 6]; const num = 9;
配列全体の合計は 3 + 8 + 2 + 6 = 19 であり、これを 9 で割ると余りは 1 になります。ここで部分配列 [8, 2] を削除すると、残りの合計は 3 + 6 = 9 となり、見事に 9 で割り切れます。1つの要素だけを削除してもこの条件は満たせないため、期待される出力は次のとおりです。
const output = 2;
解法のコード
以下が実際の実装コードです。
const arr = [3, 8, 2, 6];
const num = 9;
const minimumDeletion = (arr = [], num) => {
// 配列全体の合計をnumで割った余り
const diff = arr.reduce((a, b) => a + b) % num;
// 余りが0なら削除不要、それ以外は仮の最大値を設定
let res = diff == 0 ? 0 : arr.length;
// 累積和の余りごとの最初の出現位置を記録するマップ
for (let i = 0, sum = 0, map = {0: -1}; i < arr.length; i++) {
sum += arr[i];
// 削除候補となる部分配列の終点に対応する余りを計算
const target = (sum % num - diff + num) % num;
if (map[target] != undefined) {
res = Math.min(res, i - map[target]);
}
map[sum % num] = i;
}
// 条件を満たす削除が不可能な場合は-1を返す
return res == arr.length ? -1 : res;
};
console.log(minimumDeletion(arr, num));
アルゴリズムのポイント
- 余りの計算:まず配列全体の合計を
numで割った余り(diff)を求めます。diffが 0 であれば、そもそも削除は一切不要なので答えは 0 です。 - 削除すべき部分配列の性質:「合計を
numで割った余りがdiffと一致する部分配列」を見つけて取り除けば、残りの合計は必ずnumの倍数になります。 - 累積和とハッシュマップによる高速化:各時点での累積和の余りと、その余りが最初に出現したインデックスをマップに記録します。これにより、二重ループを使わずに O(n) の時間計算量で最短の部分配列を効率的に探索できます。
- 不可能なケースへの対応:どの部分配列を削除しても条件を満たせない場合は -1 を返す仕様になっています。
実行結果
上記のコードをコンソールで実行すると、次の出力が得られます。
2
-
JavaScriptで配列内の正の数だけを合計する方法
問題正と負の数値が混在した配列を受け取り、その中に含まれる正の数すべての合計を計算して返すJavaScript関数を作成する必要があります。たとえば、[5, -5, -3, -5, -7, -8, 1, 9] という配列が与えられた場合、正の数は 5、1、9 の3つなので、期待される出力は 15 となります。解決コード以下がその実装例です。const arr = [5, -5, -3, -5, -7, -8, 1, 9]; const sumPositives = (arr = []) => { const isPositive = num => type
-
JavaScriptで循環配列の最大部分配列和を求める方法
問題JavaScriptで、整数の配列 arr を唯一の引数として受け取る関数を作成します。この配列 arr は循環配列として扱います。循環配列とは、配列の末尾の要素の後に先頭の要素が続く構造のことです。私たちのタスクは、arr の空でない部分配列の中から、要素の合計が最大となる値を見つけて返すことです。入出力の例入力:const arr = [2, -2, 3, -1];出力:const output = 4;出力の説明:この場合、最適な部分配列は [3, -1, 2] です。末尾の -1 の後に先頭の 2 が続くため、3 + (-1) + 2 = 4 となり、これが最大の合計値になります。