JavaScriptで最大num個の0を1に変更した後の最長連続1の長さを求める方法
問題
JavaScriptの関数を作成します。この関数は、0と1のみを含むバイナリ配列arrを第一引数に、数値numを第二引数として受け取ります。
配列内の0を最大num個まで1に変更できるとき、変更後の配列において1のみが連続する最長の(連続した)部分配列の長さを返す必要があります。
例えば、関数への入力が以下の場合 −
const arr = [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0];
const num = 2;
このときの出力は以下のようになります −
const output = 6;
出力の説明
2つの0を1に変更すると、配列の末尾6要素がすべて1になるためです。
スライディングウィンドウによるアプローチ
この問題は「スライディングウィンドウ(尺取り法)」と呼ばれる手法で効率的に解けます。左右2つのポインタを使用し、ウィンドウ内に含まれる0の数がnumを超えない範囲でウィンドウを維持・拡張していきます。
コード例
この問題を解くコードは以下のとおりです −
const arr = [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0];
const num = 2;
const longestOnes = (arr = [], num = 1) => {
let max = 0;
let left = 0;
let curr = num;
for(let right = 0; right < arr.length; right++){
if(arr[right] === 0){
curr -= 1;
};
while(curr < 0){
if(arr[left] === 0){
curr += 1;
};
left += 1;
};
max = Math.max(max, right - left + 1);
};
return max;
};
console.log(longestOnes(arr, num));
コードの解説
このアルゴリズムの動作を簡単に説明します:
- rightポインタで配列を先頭から順に走査し、要素が0であれば許容カウントcurrを1減らします。
- currが負になった場合、ウィンドウ内の0の数が許容数を超えているため、leftポインタを右に進め、0を通過するたびにcurrを1増やして回復させます。
- 各ステップで現在のウィンドウ幅(right - left + 1)を計算し、最大値maxを更新します。
この方法では各要素が最大2回しか走査されないため、時間計算量はO(n)、空間計算量はO(1)という非常に効率的な実装になります。
出力
コンソールには以下のように出力されます −
6
-
JavaScriptで各要素より右側にある小さい数字の個数を数える方法
問題概要今回は、数値の配列を唯一の引数として受け取るJavaScript関数を作成します。この関数は、入力された配列をもとに新しい配列を生成します。新しく作られる配列の各要素には、元の配列内で「対応する要素より右側に位置し、かつその値より小さい要素」の個数が格納されます。たとえば、次のような配列を入力したとします。const arr = [4, 7, 1, 4, 7, 5, 3, 8, 9];この場合、期待される出力は以下の通りです。const output = [2, 4, 0, 1, 2, 1, 0, 0, 0];出力結果の解説先頭の「4」よりも右側にあり、値がそれより小さい要素は「1」と
-
JavaScriptで最長のペアチェーンを見つける方法
問題数値ペア(組)の配列 arr を唯一の引数として受け取り、形成可能な最長チェーンの長さを返す JavaScript 関数を作成します。各ペアにおいて、最初の数値は必ず 2 番目の数値より小さいものとします。ここで、ペア (c, d) が別のペア (a, b) の後に続けられるのは、b < c が成り立つ場合に限られると定義します。このルールに従ってペアの連鎖(チェーン)を形成することができ、本関数はその中で最も長いチェーンの長さを求める必要があります。入力例const arr = [ [1, 2], [2, 3], [3, 4] ];出