题目描述
有效括号字符串为空 ""
、"(" + 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:
输入:s = "(()())(())" 输出:"()()()" 解释: 输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())", 删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"。
示例 2:
输入:s = "(()())(())(()(()))" 输出:"()()()()(())" 解释: 输入字符串为 "(()())(())(()(()))",原语化分解得到 "(()())" + "(())" + "(()(()))", 删除每个部分中的最外层括号后得到 "()()" + "()" + "()(())" = "()()()()(())"。
示例 3:
输入:s = "()()" 输出:"" 解释: 输入字符串为 "()()",原语化分解得到 "()" + "()", 删除每个部分中的最外层括号后得到 "" + "" = ""。
提示:
1 <= s.length <= 105
s[i]
为'('
或')'
s
是一个有效括号字符串
知识储备
//假设栈内的数据类型是data
class data {
int a;
intb;
public:
data(int x, int y):a(x), b(y) {}
};
data d(1,2);
emplace和push相同点
1.直接传入对象(已构造好的对象)
S.push(d) 或 S.emplace(d);
2.在传入时候构造对象
S.push(data(1,2));
S.emplce(data(1,2));
emplace和push不同点
·emplace可以直接传入构造对象需要的元素
S.emplace(1,2)
解释:emplace传入构造对象所需要的元素,自动调用其构造函数生成对象,然后放在容器内(比如这里传入了1,2,它会自动调用一次data(1,2))
而push,只能让其构造函数构造好了对象之后,使用拷贝构造函数,将拷贝后的对象放入容器
相当于emplace直接把原料拿进家,自动用原料生成最终对象。而push生成实体后,再复制到自己家里,多了复制这一步。
所以emplace相对于push,使用第三种方法会更节省内存。
注意:emplace_back(type) 对应 push_back(type)
emplace(i, type) 对应于 insert(type, i)
emplace_front(type) 对应于 push_front()
但是,对于stack 和 queue,只有push操作,所以也只有emplace操作,此时它们是相对应的。
题目中给出的字符串是由小括号"(",")"构成的。什么是有效的括号字符串呢?
空字符串""
左右完全匹配的括号,如"()","(())","(()())"。
哪些不是有效的括号字符串呢?
左右括号数不等的,如"(","(()","(((()"
左右顺序错了的,如")(","))("
题目中所谓的「原语」就是不能再拆分成两个有效括号字符串A+B的。
所有的「原语」,它的整体就是一个完整的括号匹配字符串,无法再一刀两断了。
而「非原语」,把它从某个部分切开以后,可以变成两个完全匹配的括号字符串。
解题方法
栈
题目核心就是让我们实现一个括号匹配算法。
谈到括号匹配算法,就会想到「栈」。
本题的做法不难,核心就是:当栈为空的时候,说明已经形成了『原语』。
从左向右遍历字符串s
当遇到"("时,将其入栈;
当遇到")"时,说明匹配了前面最近一个"(",因此将栈顶弹出;
而结果字符串res,需要根据当前的"("或者")"是不是「原语」的开头和结束来决定。
当"("入栈前,栈是空,说明"("是『原语』的开头,因此不放入res中。
当遇到")"弹出栈顶以后,栈是空,说明")"是『原语』的结束,因此不放入res中。
C++代码
Classsolution{
Public:
stringremoveOuterParentheses(strings){
stringres;
stack<char>st;
for(autoc:s){
if(c==‘)’){
st.pop();
}
if(!st.empty()){
res.push_back(c);
}
if(c==‘(’){
st.emplace();
}
}
returnres;
}
};
-
时间复杂度:O(n),n是输入s的长度,仅需遍历字符串一次
-
空间复杂度:O(n)需要使用栈,栈深最大为n