一、题目描述
有效括号字符串为空 ""、"(" + 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 <= 105s[i]为'('或')'s是一个有效括号字符串
本题就是要我们把输入字符串中所有的最外层括号删除,那想要删除所有的最外层括号,最简单的方法将输入字符串按最外层括号拆分为多个子串放入数组
然后循环数组,将每个子串的最外层括号删除,最后将剩余子串连接即可组成结果字符串
但是这种操作需要进行两次循环,并不是本题的最优解法
我们可以在一次循环输入字符串的过程中,直接拆解出需要的结果字符串
解题思路如下:
- 初始化
l = 0记录左括号数量,r = 0记录右括号数量,left = 0记录本次区间开始下标,res = ""记录结果字符串 - 遍历字符串,并更新相关变量。当当前字符为
(的时候,l++,反之r++ - 当
l === r的时候,说明找到了一组最外层括号,此时left下标指向左括号下标,当前遍历下标i指向右括号下标,截取两下标中间部分字符,即为我们需要的结果字符串的一部分 - 重置
l = 0,r = 0,left = i+1,重复以上过程,直到输入字符串遍历完成 - 此时
res中保存的就是求得的结果字符串
整体过程如下:
代码如下:
var removeOuterParentheses = function(s) {
// 记录左括号数量
let l = 0,
// 记录右括号数量
r = 0,
本次区间开始下标
left = 0,
// 结果字符串
res = '';
// 遍历输入字符串
for(let i = 0;i<s.length;i++){
// 更新左右括号数量
if(s[i]==='(') l++;
else r++;
// 当左右括号数量相同,说明此时找到了最外层括号
if(l===r){
// 截取当前最外层括号的内部字符串
res += s.substring(left+1,i);
// 重置左右括号数量为0
l = 0;
r = 0;
// 更新开始下标为下一个最外层括号的开始下标
left = i+1;
}
}
// 返回结果字符串
return res;
};
如有任何问题或建议,欢迎留言讨论!