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

JavaScriptで隣接する要素よりも大きい「ピーク要素」を検索する方法

本記事では、数値の配列を第1引数(唯一の引数)として受け取るJavaScript関数を作成します。

この関数の役割は、配列の中から「すぐ左隣の要素」と「すぐ右隣の要素」のどちらよりも大きい値(いわゆるピーク要素)を見つけて返すことです。該当する要素が複数存在する場合は、そのうちのどれか1つを返せば問題ありません。

例として、次のような入力配列が与えられた場合を考えてみましょう。

const arr = [3, 6, 7, 9, 8, 2, 5];

このとき期待される出力は次のとおりです。

const output = 9;

9は左隣の7よりも大きく、右隣の8よりも大きいため、条件を満たす要素だからです。

二分探索を応用したアプローチ

この問題は典型的な「ピーク要素の探索」であり、先頭から順に比較していく線形探索でも解けますが、二分探索(バイナリサーチ)を応用すれば、計算量をO(n)からO(log n)まで削減できます。配列がソートされていなくても適用できる点がポイントです。

具体的な手順は以下のようになります。

  • まず配列内の中央付近の要素に着目します。
  • その要素が前後両方の要素より大きければ、そこがピークなので現在のインデックスの値を返します。
  • 右隣の要素の方が大きい場合は、右側に必ずピークが存在するため、右半分を再帰的に探索します。
  • 左隣の要素の方が大きい場合は、左側に必ずピークが存在するため、左半分を再帰的に探索します。

実装コード

上記の手順を実際にコードにすると、以下のようになります。

const arr = [3, 6, 7, 9, 8, 2, 5];
const greaterThanAdjacent = (arr = [], start = 0, end = arr.length) => {
    let mid = start + Math.floor((end - start) / 2);
    let curr = arr[mid];
    let prev = mid-1 < 0 ? -Infinity : arr[mid-1];
    let next = mid+1 > arr.length-1 ? -Infinity : arr[mid+1];
    if (curr > prev && curr > next){
        return arr[mid];
    }
    if (curr < next){
        return greaterThanAdjacent(arr, mid+1, end);
    }
    if (curr > next){
        return greaterThanAdjacent(arr, start, mid-1);
    }
    return null;
};
console.log(greaterThanAdjacent(arr));

コードのポイント

この実装で注目したいのは、配列の端の処理です。midが0や配列末尾にある場合、隣接要素が存在しないため、範囲外を-Infinityとして扱っています。これにより、「先頭要素」や「末尾要素」も正しくピーク候補として評価できるようになっています。

実行結果

上記のコードを実行すると、コンソールには次のように出力されます。

9

このように、二分探索の考え方を少し変形させるだけで、ソートされていない配列からでも効率よくピーク要素を見つけることができます。大規模なデータセットを扱う際には、特に有効な手法と言えるでしょう。

  1. JavaScriptで「次に大きい要素までの距離」を求めるアルゴリズム

    問題概要 数値の配列 arr を唯一の引数として受け取るJavaScript関数を作成します。 この関数の役割は、入力配列をもとに新しい配列を構築することです。新しい配列の各要素には、「現在の要素よりも大きい要素が右側に現れるまでの距離」(インデックスの差)を格納します。もし現在の要素より大きい要素が右側に存在しない場合は、対応する位置に 0 を入れます。最後に、この結果配列を返します。 入力例 const arr = [12, 13, 14, 11, 16, 10, 12, 17, 19, 18]; 出力例 const output = [1, 1, 2, 1, 3, 1, 1, 1,

  2. Pythonで「前の要素より大きい要素の数」に基づいてマトリックス(ネストされたリスト)をソートする方法

    はじめにPythonでは、各行(リスト)の中に「直前の要素より大きい要素」がいくつ含まれているかを基準にして、マトリックス(リストのリスト)を並べ替えることができます。このような処理を行うには、リスト内包表記とlen() メソッドを組み合わせた関数を定義し、それを sort() の key 引数に渡すのが一般的です。以下に具体的な実装例を示します。サンプルコードdef fetch_greater_freq(row):    return len([row[idx] for idx in range(0, len(row) - 1) if row[idx]