JavaScriptで中央にピークのある配列(山型配列)かどうかを判定する方法
問題
数値の配列 arr を第1引数(唯一の引数)として受け取るJavaScript関数を作成します。
この関数の役割は、入力された配列が「中央にピークのある配列(山型配列)」であるかどうかを判定することです。条件を満たしていれば true を、満たしていなければ false を返します。
山型配列となるための条件
配列の長さが 3 以上であること(arr.length >= 3)
0 < i < arr.length - 1 を満たすインデックス i が存在し、以下の両方が成り立つこと:
arr[0] < arr[1] < ... < arr[i-1] < arr[i](頂上までは単調に増加する)
arr[i] > arr[i+1] > ... > arr[arr.length - 1](頂上からは単調に減少する)
入力例と出力例
たとえば、関数への入力が次の配列だった場合:
const arr = [2, 6, 7, 9, 5, 3, 1];
期待される出力は次の通りです。
const output = true;
出力の解説
この配列は値 9 を頂点として、そこまでは一方向に増加し続け、頂上を境に一方向へ減少し続けているため、山型配列の条件を満たしています。
実装コード
この処理を実現するコードは以下の通りです。
const arr = [2, 6, 7, 9, 5, 3, 1];
const isCentrallyPeaked = (arr = []) => {
let ind = undefined;
for (let i = 1; i <= arr.length - 1; i++) {
if (ind === undefined) {
if (arr[i] < arr[i - 1]) {
ind = i - 1
} else if (arr[i] === arr[i - 1]) {
return false
}
} else if (arr[i] >= arr[i - 1]) {
return false
}
}
return ind > 0 && ind < arr.length - 1
};
console.log(isCentrallyPeaked(arr));コードの解説
変数 ind はピーク(山頂)のインデックスを記録するためのもので、初期値は undefined です。
forループで隣接する要素同士を比較しながら配列を走査します。
登り坂の間(ind === undefined):arr[i] が前の要素より小さくなった時点で減少に転じたと判断し、その直前のインデックス i - 1 をピークとして記録します。また、隣接要素が等しい場合は厳密な増加・減少ではないため即座に false を返します。
下り坂の間(ind 決定後):再び増加や同値が現れた場合は false を返します。
最後に、ピークの位置が先頭でも末尾でもない(0 より大きく、arr.length - 1 未満である)ことを確認しています。これにより、配列全体が増加のみ、または減少のみの場合に false が返されるようになっています。
実行結果
コンソールには次のように出力されます。
true
-
JavaScriptの配列で使えるスプレッド演算子(...)の使い方
スプレッド構文(...)を使うと、配列などのイテラブルなオブジェクトを、0個以上の引数が期待される場所で展開することができます。これにより、配列の要素をまとめて関数の引数として渡すことが可能になります。スプレッド演算子の基本例えば、5つの引数を受け取る関数に対して5つの要素を持つ配列を渡したい場合、従来の書き方では各要素を個別に指定する必要がありました。しかし、スプレッド演算子を使えば「add(...arr)」のように記述するだけで、配列の各要素が順番に引数として展開されて渡されます。スプレッド演算子は、配列の結合やコピーなど、さまざまな場面でも活用できる便利な構文です。以下は、JavaScr
-
【JavaScript】中央にピークを持つ配列のピークインデックスを二分探索で見つける方法
中央にピークを持つ配列とはある配列 arr が「中央にピークを持つ配列(centrally peaked array)」であるとは、以下の条件を満たすことを指します。arr.length >= 30 < i < arr.length - 1 を満たす添字 i が存在し、次の条件が成り立つarr[0] < arr[1] < ... arr[i-1] < arr[i](インデックス i まで単調に増加する)arr[i] > arr[i+1] > ... > arr[arr.length - 1](インデックス i 以降は単調に減少する)つまり、