【JavaScript】部分配列の合計として表せない最小の正の整数を求めるアルゴリズム
問題の概要
まず、正の整数が昇順にソートされた配列を考えてみましょう。
const arr = [1, 3, 6, 10, 11, 15];
このような配列を引数として受け取り、「元の配列の部分配列(要素の集まり)の合計として表すことができない最小の正の整数」を返す関数 findSmallest() を作成します。
例えば、上記の配列の場合、どの部分配列を足し合わせても到達できない最小の正の整数は「2」です。それでは、この関数のコードを書いていきましょう。
アルゴリズムの考え方
配列があらかじめソートされているため、この問題は線形時間 O(n) で解くことができます。
手順は以下の通りです。
最初に、答えとなる候補値を「1」で初期化します。これは、答えが取り得る最小の値が1だからです。
続いて、配列を先頭から順に走査し、注目している要素を候補値に加算していきます。このとき、もし現在の要素が候補値よりも大きければ、そこで答えが確定します。なぜなら、それまでの要素の合計でカバーできる範囲に欠落が生じていることを意味するからです。要素が候補値以下であるうちは、走査を継続します。
コード例
const arr = [1, 3, 6, 10, 11, 15];
const findSmallest = arr => {
let res = 1;
for(let ind = 0; ind < arr.length && arr[ind] <= res; ind++){
res += arr[ind];
}
return res;
};
console.log(findSmallest(arr));実行結果
コンソールには次のように出力されます。
2
-
JavaScriptで循環配列の最大部分配列和を求める方法
問題JavaScriptで、整数の配列 arr を唯一の引数として受け取る関数を作成します。この配列 arr は循環配列として扱います。循環配列とは、配列の末尾の要素の後に先頭の要素が続く構造のことです。私たちのタスクは、arr の空でない部分配列の中から、要素の合計が最大となる値を見つけて返すことです。入出力の例入力:const arr = [2, -2, 3, -1];出力:const output = 4;出力の説明:この場合、最適な部分配列は [3, -1, 2] です。末尾の -1 の後に先頭の 2 が続くため、3 + (-1) + 2 = 4 となり、これが最大の合計値になります。
-
Pythonで配列の部分集合の和として表せない最小の正整数を求めるアルゴリズム
昇順にソートされた正の数の配列が与えられたとき、その配列の任意の部分集合の要素の合計として表すことのできない、最小の正の値を見つける必要があります。この問題は O(n) の時間計算量で解くことが求められます。例えば、入力が A = [1, 4, 8, 12, 13, 17] の場合、出力は 2 になります。これは、1 は単独の要素として表せますが、2 はどの部分集合の合計によっても作れないためです。解法のアプローチこの問題は、貪欲法(Greedy法)の考え方を使うことで線形時間で解けます。手順は以下の通りです。n := 配列 A のサイズanswer := 1(初期値)i を 0 から n-1