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

JavaScriptで隣接しない要素から最大合計の部分集合を求める方法

整数の配列を受け取り、その中から互いに隣接していない要素で構成される部分集合のうち、合計が最大になるものを見つけるJavaScript関数を作成する必要があります。

そして最終的に、その部分集合の合計を計算して返します。

問題の例

例えば、入力配列が以下の場合を考えてみましょう。

const arr = [3, 5, 7, 8, 10];

この場合の出力は 20 になります。これは、隣接しない要素で構成される部分集合として「3, 7, 10」を選んだとき、その合計が 20 となり、これが最大となるためです。

サンプルコード

const arr = [3, 5, 7, 8, 10];
const maxSubsetSum = (arr = []) => {
    let min = -Infinity
    const helper = (arr, ind) => {
        if ( ind < 0 ){
            return min
        };
        let inc = helper(arr, ind-2);
        let notInc = helper(arr, ind-1);
        inc = inc == min ? arr[ind] : Math.max(arr[ind], arr[ind] + inc);
        return Math.max( inc, notInc );
    };
    return helper(arr, arr.length - 1);
};
console.log(maxSubsetSum(arr));

コードの解説

このアルゴリズムは再帰を利用したアプローチです。各インデックスの位置において、次の2つの選択肢を比較します。

  • 現在の要素を選ぶ場合:隣接する直前の要素は選べないため、2つ前まで遡って計算した結果に現在の要素を加えた値になります。
  • 現在の要素を選ばない場合:1つ前まで遡って計算した結果をそのまま利用します。

この2つの値のうち大きい方を順に採用していくことで、最終的な最大合計が求まります。

なお、この実装は再帰をそのまま使っているため、配列の長さが増えると計算量が指数的に膨らむという弱点があります。実際の開発では、メモ化(キャッシュ)動的計画法(DP)を組み合わせて処理を効率化するのが一般的です。

実行結果

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

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

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

  2. C++で指定した合計値になる最大サイズの部分集合を求める方法

    問題文 N個の要素からなる配列と合計値が与えられたとき、要素の合計が指定された値と一致する「最大サイズの部分集合」のサイズを求める問題です。 例 入力配列が arr = { 2, 3, 5, 10 }、合計値が sum = 20 の場合、出力は 4 になります。 なぜなら、 2 + 3 + 5 + 10 = 20 となり、配列の全要素を選んだ部分集合の合計が指定された合計値と一致するためです。 アルゴリズム この問題は動的計画法(DP)を用いて効率的に解くことができます。 まず、通常の部分和問題と同様に subset[i][j] というブール型のDPテーブルを用意します。これは「最初の j