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

C++で有効な括弧列にするために追加すべき括弧の最小数

問題文

開き括弧「(」と閉じ括弧「)」のみで構成された文字列が与えられます。この文字列を有効な括弧列(すべての括弧が正しく対応している状態)にするために、追加が必要な括弧の最小個数を求めてください。

str = "((()" の場合、末尾に閉じ括弧「))」を2つ追加して "((()))" とすれば有効な括弧列になります。したがって答えは 2 です。

アルゴリズム

単純に「開き括弧の総数と閉じ括弧の総数の差の絶対値」を答えとする方法は、")(" のように閉じ括弧が開き括弧より先に現れるケースで誤った結果(0)を返してしまうため注意が必要です。正しく求めるには、文字列を先頭から走査しながら対応する相手を持たない括弧の数を数えます。

  1. 未対応の開き括弧の数 open と、未対応の閉じ括弧の数 close を 0 で初期化します。
  2. 文字列を左から右へ1文字ずつ走査します。
  3. 「(」を見つけたら open を1増やします。
  4. 「)」を見つけたら、open > 0 なら対応する開き括弧とマッチするので open を1減らし、open == 0 なら close を1増やします。
  5. 走査終了時の open + close が求める答えです。

C++実装例

#include <iostream>
#include <string>
using namespace std;

int requiredParentheses(const string& str) {
    int open = 0, close = 0;
    for (char c : str) {
        if (c == '(') {
            ++open;
        } else if (c == ')') {
            if (open > 0) {
                --open;   // 対応する開き括弧とマッチ
            } else {
                ++close;  // マッチする開き括弧がない
            }
        }
    }
    return open + close;
}

int main() {
    string str = "((()";
    cout << "Required parentheses = " << requiredParentheses(str) << endl;
    return 0;
}

このプログラムをコンパイルして実行すると、次の出力が得られます。

Required parentheses = 2

計算量

  • 時間計算量: O(n) — 文字列を1回走査するだけです。
  • 空間計算量: O(1) — カウンタ変数2つのみを使用します。
  1. C++で文字列を回文にするために必要な最小削除文字数を求める方法

    問題の概要長さ n の文字列が与えられたとき、その文字列を回文にするために削除が必要な最小の文字数を求めるのがこの問題の目的です。たとえば、入力文字列が「abcda」の場合、先頭と末尾以外の2文字を削除すれば回文を作ることができます。「b」と「c」を削除すると → 「ada」(回文になります)「c」と「d」を削除すると → 「aba」(回文になります)「b」と「d」を削除すると → 「aca」(回文になります)アルゴリズムの考え方この問題は「最長回文部分列(Longest Palindromic Subsequence: LPS)」の考え方を使うと効率的に解けます。手順は次のとおりです。与えら

  2. Pythonで括弧列を有効にするための最小追加数を求める方法

    問題の概要 ( と ) だけで構成された文字列 S が与えられます。任意の位置に最小限の括弧を追加して、結果として得られる文字列を「有効な括弧列」にすることを考えます。括弧列が有効であるとは、次のいずれかの条件を満たすことを指します。 空文字列である XY(X と Y を連結した形)と表せ、X と Y がどちらも有効な文字列である (A) という形で表せ、A が有効な文字列である たとえば、文字列が "()))((" の場合、これを有効にするには 4 つの括弧を追加する必要があります。 解法のアプローチ この問題はスタックの考え方を使うとシンプルに解決できます。具体的な