校招编程题目(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] 卡特兰数问题总结

猜你喜欢

转载自blog.csdn.net/Jingle_cjy/article/details/77913980