1021.删除最外层的括号

【LetMeFly】1021.删除最外层的括号

力扣题目链接:https://leetcode.cn/problems/remove-outermost-parentheses/

有效括号字符串为空 """(" + A + ")"A + B ,其中 AB 都是有效的括号字符串,+ 代表字符串的连接。

例如,"""()""(())()""(()(()))" 都是有效的括号字符串。
如果有效字符串 s 非空,且不存在将其拆分为 s = A + B 的方法,我们称其为原语(primitive),其中 AB 都是非空有效括号字符串。

给出一个非空有效字符串 s,考虑将其进行原语化分解,使得:s = P_1 + P_2 + ... + P_k,其中 P_i 是有效括号字符串原语。

s 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 s

示例 1:

1
2
3
4
5
输入:s = "(()())(())"
输出:"()()()"
解释:
输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())"
删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"

示例 2:

1
2
3
4
5
输入:s = "(()())(())(()(()))"
输出:"()()()()(())"
解释:
输入字符串为 "(()())(())(()(()))",原语化分解得到 "(()())" + "(())" + "(()(()))"
删除每个部分中的最外层括号后得到 "()()" + "()" + "()(())" = "()()()()(())"

示例 3:

1
2
3
4
5
输入:s = "()()"
输出:""
解释:
输入字符串为 "()()",原语化分解得到 "()" + "()"
删除每个部分中的最外层括号后得到 "" + "" = ""

提示:

  • $1\leq s.length\leq 10^5$
  • s[i]‘(’‘)’
  • $s$ 是一个有效阔和字符串

题目大意

题目大概意思就是要把原字符串拆分成(...)(...)(...)的样子。

例如某个字符串可以拆分成(a)(b)(c)(d),那么就返回abcd

其中,我们把(a)(b)(c)(d)记为原语

也就是说要把由原语组成的字符串拆分成每个原语,然后把每个原语去掉两边的括号并按顺序拼接后返回。

思路

用变量$left$来记录未配对的左括号的数量。

从左到右遍历字符串,遇到左括号$left$就$+1$,遇到右括号就$-1$。

也就是用计数来模拟栈。

方法一:模拟

遇到括号,如果计数之前$left$为$0$,那么就说明这是一个原语的*_开始。原语的最左_*括号是不用作为答案返回的,因此只有当$left$不为$0$的时候才返回当前字符。

遇到括号,如果计数之后$left$为$0$,那么就说明这是一个原语结束。原语的最括号是不用作为答案返回的,因此只有当$left$不为$0$的时候才返回当前字符。

  • 时间复杂度$O(n)$
  • 空间复杂度$O(1)$

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 原语(primitive)
class Solution {
public:
string removeOuterParentheses(string s) {
string ans;
int left = 0; // 当前有几个未配对的左括号
for (char& c : s) {
if (c == '(') {
if (left) {
ans += '(';
}
left++;
}
else {
left--;
if (left) {
ans += ')';
}
}
}
return ans;
}
};

同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/125015777


1021.删除最外层的括号
https://blog.letmefly.xyz/2022/05/28/LeetCode 1021.删除最外层的括号/
作者
Tisfy
发布于
2022年5月28日
许可协议