持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
题目
有效括号字符串为空 ""、"(" + 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 <= 10^5s[i]为'('或')'s是一个有效括号字符串
思考
本题难度简单。但是实际上没那么简单啊!
首先是读懂题意。有效的括号字符串有哪些呢?比如 "","()","(())()" 和 "(()(()))"。「原语」就是不能再拆分成两个有效括号字符串 A + B的字符串,比如字符串"()()",原语化分解得到 "()" + "()"。那么,我们接下来考虑如何解决这道题。
本题是括号匹配类型的题目,我们可以使用栈!遍历给出的字符串,当遇到"("时,入栈前,栈是空,说明 "(" 是原语字符串的最外层括号的开头,因此不放入 res中。当遇到 ")" 弹出栈顶以后,栈是空,说明 ")" 是原语字符串的最外层括号的结束,因此不放入 res中。因此,pop之后判断是否将当前字符加入res,push之前也要判断。
考虑到我们需要遍历一次字符串,因此时间复杂度是O(n),其中 n 为字符串的长度。下面是具体代码。
解答
方法一:栈
/**
* @param {string} s
* @return {string}
*/
var removeOuterParentheses = function(s) {
let res = ''
const stack = []
for (let i = 0; i < s.length; i++) {
let c = s[i]
if (c === ')') {
stack.pop()
}
if (stack.length) {
res += c
}
if (c === '(') {
stack.push(c)
}
}
return res
}
// 执行用时:68 ms, 在所有 JavaScript 提交中击败了49.08%的用户
// 内存消耗:43.1 MB, 在所有 JavaScript 提交中击败了24.54%的用户
// 通过测试用例:59 / 59
复杂度分析:
- 时间复杂度:O(n),其中 n 为字符串的长度。
- 空间复杂度:O(n)。