[LeetCode] 1021. Remove Outermost Parentheses
LeetCode 1021. Remove Outermost Parentheses (删除最外层的括号) Diffculty: Eazy
Question
A valid parentheses string is either empty (""), "(" + A + ")", or A + B, where A and B are valid parentheses strings, and + represents string concatenation. For example, "", "()", "(())()", and "(()(()))" are all valid parentheses strings.
A valid parentheses string S is primitive if it is nonempty, and there does not exist a way to split it into S = A + B, with A and B nonempty valid parentheses strings.
Given a valid parentheses string S, consider its primitive decomposition: S = P_1 + P_2 + ... + P_k, where P_i are primitive valid parentheses strings.
Return S after removing the outermost parentheses of every primitive string in the primitive decomposition of S.
Note:
S.length <= 10000S[i]is"("or")"Sis a valid parentheses string
有效括号字符串为空 ("")、"(" + A + ")" 或 A + B,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。例如,"","()","(())()" 和 "(()(()))" 都是有效的括号字符串。
如果有效字符串 S 非空,且不存在将其拆分为 S = A + B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。
给出一个非空有效字符串 S,考虑将其进行原语化分解,使得:S = P_1 + P_2 + ... + P_k,其中 P_i 是有效括号字符串原语。
对 S 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 S。
提示:
S.length <= 10000S[i]为"("或")"S是一个有效括号字符串
Example
Example 1
1 | Input: "(()())(())" |
Example 2
1 | Input: "(()())(())(()(()))" |
Example 3
1 | Input: "()()" |
Solution
题意分析
- Input:一个有效括号字符串
S - Output:原语化分解,删除分解中每个原语字符串的最外层括号的
S
Java
My Solution 1: Loop
解题思路
将字符串 S 转为字符数组(char[]),遍历判断字符是 ( 或 )。是 ( 则计数 +1,是 ) 则计数 -1。如计数为 0,则表示一个有效的括号字符串的结束,以此截出有效的括号字符串,去除首尾的括号后,加到结果中。
解题步骤
- 定义输出变量(
StringBuilder) ->result - 定义临时存储变量(
StringBuilder) ->temp - 定义计数变量(
int) ->num - 将字符串
S转为字符数组 ->s - 循环字符数组
s->c- 将字符
c存到临时变量temp中 - 判断字符是
(或)。是(则计数num++,是)则计数num-- - 判断
num是否为0,如为0,则去除temp首尾的括号后,加到result中,并重新初始化temp
- 将字符
- 循环结束后,返回结果变量 ->
result.toString()
Code
初版
1 | public String removeOuterParentheses(String S) { |
优化版
1 | public String removeOuterParentheses(String S) { |
Complexity Analysis
- 时间复杂度:$O(n)$
- 空间复杂度:$O(n)$
LeetCode Discuss Solution 1: Loop
Code
1 | public String removeOuterParentheses(String S) { |
Complexity Analysis
- 时间复杂度:$O(n)$
- 空间复杂度:$O(n)$
解题思路
与我的解决思路差不多,代码更简洁。
LeetCode Discuss Solution 2: Stack
Code
1 | public String removeOuterParentheses(String s) { |
Complexity Analysis
- 时间复杂度:$O(n)$
- 空间复杂度:
解题思路
利用堆栈(Stack)的先进后出,后进先出的原理。遇到 ( 就进栈,遇到 ) 就出栈。
Summary
这个问题的难点在于如何原语化分解字符串(即最外层的每一个 () 或 ((XX)(XX)))或者说如何确认 ( or ) 是需要被删除的。
就需要利用 ( 或 ) 是成对出现的这点,( 必定有一个 ),(( 必定有一个 ))。
以上的两种解题思路其实是相似的,区别只在于一个是使用自增自减的方式判断原语,另一个是利用堆栈的先进后出的方式判断原语。