校招編程題目(1) C++:括號匹配方案(京東)

題目描述

輸入一個長度爲n的字符串(0<=n<=20)只包含’(‘和’)’。對於這個字符串如”(())”,”()()”是匹配的,”)(“,”())(“都不是括號匹配的。
刪除最左邊的’(‘,從剩下的字符串中刪除任意的’)’,使得刪除後的字符串仍然是括號匹配的。
對整個字符串重複該刪除操作,直到刪除了整個字符串。問這樣的括號匹配方案有多少個?(只要有一次刪除的右括號’)’不同則認爲是一個不同的方案)

樣例

輸入 (((())))
輸出 24

輸入 ()()()
輸出 1

思路

由於字符串長度最大隻有20,可以考慮使用暴力枚舉,遞歸處理。

答案

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

int count(string str, int len, int left) {
    // cout << str << " " << left << endl;

    if(len<left || len<=0 || left<0) return 0;
    if(left==0) return 1;

    int ret=0, i=0;
    // 找到目前字符串的最左左括號位置並刪除 
    for(; i<len; i++){
        if(str[i] == '('){
            str[i] = '-';
            break;
        }
        // 假如字符串的首位出現右括號表示之前的刪除操作出現不合法
        // 則該方案不可行 
        if(str[i] == ')') return 0; 
    }
    // 枚舉剩下的右括號刪除後是否合法 
    int change = -1; 
    for(int j=i+1; j<len; j++) {
        if(change==-1 && str[j]==')'){
            str[j] = '-';
            change = j;
            ret += count(str, len, left-2);
        } 
        if(change != -1){
            str[change] = ')';
            change = -1;
        }
    }
    return ret;
}

int main(){
    string str;
    cin >> str; // "(", ")", "-"表示刪除 
    int len = str.length();
    bool illegal = false;
    for(int i=0; i<len; i++){
        if(str[i]!='(' && str[i] != ')'){
            cout << "輸入不合法!" << endl; 
            illegal = true;
            break;
        }
    }
    if(!illegal) 
        cout << count(str, len, len) << endl;

    return 0;
} 

思路擴展

這種匹配的題目常常與卡特蘭數扯上關係,比如輸入括號對數n,輸出匹配方案數。

參考及相關題目

[1] 卡特蘭數
[2] 括號匹配方案(卡特蘭數)動態規劃解法
[3] 卡特蘭數問題總結

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章