一、题目描述
有效括号字符串为空 ("")、"(" + A + “)” 或 A + B,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。例如,"","()","(())()" 和 “(()(()))” 都是有效的括号字符串。
如果有效字符串 S 非空,且不存在将其拆分为 S = A+B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。
给出一个非空有效字符串 S,考虑将其进行原语化分解,使得:S = P_1 + P_2 + … + P_k,其中 P_i 是有效括号字符串原语。
对 S 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 S 。
示例1:
输入:"(()())(())"
输出:"()()()"
解释:
输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())",
删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"。
示例2:
输入:"(()())(())(()(()))"
输出:"()()()()(())"
解释:
输入字符串为 "(()())(())(()(()))",原语化分解得到 "(()())" + "(())" + "(()(()))",
删除每个部分中的最外层括号后得到 "()()" + "()" + "()(())" = "()()()()(())"。
示例3:
输入:"()()"
输出:""
解释:
输入字符串为 "()()",原语化分解得到 "()" + "()",
删除每个部分中的最外层括号后得到 "" + "" = ""。
提示:
1. S.length <= 10000
2. S[i] 为 "(" 或 ")"
3. S 是一个有效括号字符串
二、解题思路
通过题目描述,我们可以很明显的感觉到这道题要用到栈这种抽象的数据结构。由题意我们可以得到,在由字符串S的前n个位置构成的一个片段P中,若P中的左括号数与右括号数相等,则P被称为一个原语,对于每一个原语,我们需要去掉其最外端的括号。故每个原语的首个字符 “(” 是不会出现在最终的结果中的,该原语中与首字符对应的尾字符 ")"也不会出现在最终的结果中。
我们可以用数组来模拟栈的实现,用top表示栈顶指针,并用一个变量num来记录当前字符片段中 “(” 与 “)” 的数量,若下一个字符为 “(” 则对num++,若为 ")"则对num–,值得注意的是,在遍历字符串S时,我们要从S的第二个元素开始遍历,因为S的第一个元素一定是 “(” 且一定不会出现在最终的结果中。且初始的num值设为1,这样当num值为0时,表面之前的字符片段为一个原语,且num为0对应的字符一定为 “)” , 也一定不会出现在最终的结果中。我们用字符数组arr来记录最终的结果。
三、ac代码
char * removeOuterParentheses(char * s){
int len = strlen(s);
char *arr = (char *)malloc( (len + 5) * sizeof(char) ); // 动态分配数组的大小,节省空间
int top = -1;
int num = 1;
for (int i = 1; i < len; i ++ ) {
if(s[i] == '(') {
num ++;
if (num >= 2) {
arr[++top] = s[i];
}
}
if (s[i] == ')') {
num--;
if (num >= 1) {
arr[++top] = s[i];
}
}
}
arr[++top] = '\0'; //返回结果需要字符串,所以在末尾用加上'\0'
return arr;
}
执行结果:
看完不妨点个赞。