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

JavaScriptで括弧のバランスを取る:最小挿入回数を求めるアルゴリズム

問題の概要

「(」と「)」の2種類の文字のみで構成された文字列が与えられます。この文字列に対して、必要な回数だけ「(」または「)」を挿入して括弧のバランスを取る関数を作成します。

そして、その関数は文字列のバランスを取るために行った挿入の最小回数を返す必要があります。

たとえば、次のような文字列が与えられたとします。

const str = '()))';

この場合、出力は 2 になります。先頭に「((」を追加すれば文字列のバランスが取れるためです。

解決策:スタックを使ったアプローチ

この問題は、スタック(配列)を使うことで効率的に解決できます。考え方は以下のとおりです。

  • 「(」が出現したらスタックにプッシュします。
  • 「)」が出現したとき、スタックの末尾が「(」であればペアとしてポップ(取り除き)ます。
  • スタックの末尾が「(」でない場合(スタックが空の場合を含む)は、対応する開き括弧が存在しないため、プレースホルダーとして「#」をプッシュします。

最終的にスタックに残った要素の数が、バランスを取るために必要な挿入回数と一致します。

実装コード

以下が実際のコードです。

const str = '()))';
const balanceParanthesis = str => {
    let paren = [];
    for (let i = 0; i < str.length; i++) {
        if (str[i] === "(") {
            paren.push(str[i]);
        } else if (str[i] === ")") {
            if (paren[paren.length - 1] === "("){
                paren.pop();
            } else {
                paren.push("#");
            };
        };
    }
    return paren.length;
}
console.log(balanceParanthesis(str));

コードの解説

この関数は、文字列を先頭から1文字ずつ走査します。開き括弧「(」はスタックに積まれ、閉じ括弧「)」が現れた際に直前の要素が「(」であればペアとして取り除かれます。対応する開き括弧がない場合は「#」をスタックに積むことで、後から挿入が必要な「(」の数をカウントできるようにしています。

ループが終了した時点でスタックに残っている要素は、未対応の「(」または挿入すべき「)」に相当するため、その長さを返すことで最小挿入回数が求まります。

実行結果

このコードをコンソールで実行すると、次の出力が得られます。

2

このアルゴリズムの計算量は、文字列を一度だけ走査するため O(n) であり、非常に効率的です。

  1. JavaScriptのPromise(プロミス)とは?非同期処理の基本と使い方を解説

    JavaScriptのPromise(プロミス)は、作成された時点ではまだ値が確定していない非同期処理を扱うためのオブジェクトです。APIリクエストやファイルの読み込みなど、完了まで時間がかかる処理について、「いずれ結果を受け取る」という約束を表現します。Promiseは、以下の3つの状態を持ちます。pending(保留中):処理がまだ完了しておらず、成功も失敗も確定していない初期状態fulfilled(履行済み):処理が正常に完了し、結果の値が利用できる状態rejected(拒否済み):処理が失敗し、エラーの理由が利用できる状態一度fulfilledまたはrejectedに遷移したPromi

  2. JavaScriptのWeakSetとは?特徴と主要メソッド、サンプルコードをわかりやすく解説

    JavaScriptのWeakSet(ウィークセット)は、オブジェクトを格納するためのコレクションです。Setと同様に、同じオブジェクトを重複して保存することはできません。WeakSetの主な特徴弱い参照で保持する:WeakSet内のオブジェクトへの参照が他に存在しなくなると、ガベージコレクションによって自動的にメモリから解放されます。そのため、メモリリークを防ぎたい場面で役立ちます。オブジェクトのみ格納可能:数値や文字列などのプリミティブ値は追加できません。列挙できない:Setのようなsizeプロパティや反復処理の仕組みを持たず、格納されている要素の一覧を取得することはできません。WeakS