JavaScriptで配列内のすべてのピーク(局所最大値)とその位置を検出する方法
データ分析や信号処理の現場では、数値の配列の中から「山」にあたる部分、つまり局所最大値(ピーク)とその位置を特定したい場面がよくあります。本記事では、JavaScriptを使って配列内のすべてのピークと、そのインデックス位置を効率的に検出する方法を解説します。
前提となる例
まず、次のようなJavaScriptの配列を用意します。
const arr = [4, 3, 4, 7, 5, 2, 3, 4, 3, 2, 3, 4];
この配列の各要素をY軸の値としてプロットし、隣り合う要素同士をX軸上で等間隔(単位距離)に配置すると、グラフは以下のようになります。

グラフを見ると分かるように、この配列には2つの局所最大値(ピーク)が存在します。1つ目はインデックス3の値「7」、2つ目はインデックス7の値「4」です。
実装すべき処理
ここで求められているのは、整数の配列 arr を引数として受け取るJavaScript関数を作成することです。この関数は、次の2つのプロパティを持つオブジェクトを返す必要があります。
- maximas:配列内に存在する局所最大値そのものを格納した配列
- positions:それぞれの最大値に対応するインデックスを格納した配列
先ほどの配列を入力とした場合、期待される出力は次のとおりです。
const output = {
maximas: [7, 4],
positions: [3, 7]
};
コード例
実際のコードは以下のようになります。
const arr = [4, 3, 4, 7, 5, 2, 3, 4, 3, 2, 3, 4];
const findMaxima = (arr = []) => {
let positions = [];
let maximas = [];
for (let i = 1; i < arr.length - 1; i++) {
if (arr[i] > arr[i - 1]) {
if (arr[i] > arr[i + 1]) {
// 左右の隣接要素より大きい場合 → ピーク
positions.push(i);
maximas.push(arr[i]);
} else if (arr[i] === arr[i + 1]) {
// 隣接要素と同じ値が続く場合(台地状のピーク)
let temp = i;
while (arr[i] === arr[temp]) i++;
if (arr[temp] > arr[i]) {
positions.push(temp);
maximas.push(arr[temp]);
}
}
}
}
return { maximas, positions };
};
console.log(findMaxima(arr));
アルゴリズムのポイント
この関数のロジックを簡単に整理しておきましょう。
- ループは配列の両端を除いた範囲(
i = 1からarr.length - 2まで)で回します。両端の要素は左右どちらかの隣接要素が存在しないため、比較対象にならないためです。 - 現在の要素が左隣より大きく、かつ右隣よりも大きければ、それはピークであると判定できます。
- もし現在の要素が右隣と同じ値だった場合は、「同じ値が連続する平坦な部分(プラトー)」の可能性があります。そこで
whileループで同じ値が続く限り進み、その連続区間が左側より高く右側より低くなっていれば、その区間を1つのピークとして記録します。これにより、[1, 3, 3, 1]のような配列でも正しくピークを検出できます。
出力結果
上記のコードを実行すると、コンソールには次のように出力されます。
{ maximas: [ 7, 4 ], positions: [ 3, 7 ] }
このように、配列内のすべてのピークの値と、それぞれのインデックス位置を1つのオブジェクトとしてまとめて取得できました。計算量は配列の長さに対して線形時間 O(n) で済むため、大きなデータセットにも効率的に対応できる実装となっています。
-
JavaScriptで配列内の先行・後続要素が両方存在する値を検索する方法
問題の概要 整数の配列を引数として受け取り、「その要素自身より1小さい値」と「1大きい値」がどちらも同じ配列内に存在する要素だけを抜き出して、新しい配列として返すJavaScript関数を作成してみましょう。 言い換えると、ある要素 num が結果の配列に含まれるのは、num - 1 と num + 1 の両方が元の配列に存在するとき、かつそのときに限られます。 入力例と出力例 たとえば、入力配列が次の通りだったとします。 const arr = [4, 6, 8, 1, 9, 7, 5, 12]; このとき、期待される出力は次のようになります。 const output = [ 6, 8,
-
JavaScriptで2つの配列の共通要素を取得する方法(重複要素も保持)
問題 2つの配列 arr1 と arr2 をそれぞれ第1引数・第2引数として受け取る JavaScript の関数を作成する必要があります。 この関数は、両方の配列に共通して存在する要素(積集合)を求めます。さらに、ある要素が両方の配列に2回登場する場合には、結果の配列にもその要素を2回含めなければなりません。 例えば、関数への入力が次のような場合です。 const arr1 = [2, 7, 4, 6, 7, 4]; const arr2 = [7, 1, 9, 7, 4, 5]; このとき、期待される出力は次のようになります。 const output = [7, 7, 4]; 7 と