网络异常,图片无法展示
|
有效括号字符串为空 ""
、"(" + 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
是一个有效括号字符串
本题就是要我们把输入字符串中所有的最外层括号删除,那想要删除所有的最外层括号,最简单的方法将输入字符串按最外层括号拆分为多个子串放入数组
然后循环数组,将每个子串的最外层括号删除,最后将剩余子串连接即可组成结果字符串
但是这种操作需要进行两次循环,并不是本题的最优解法
我们可以在一次循环输入字符串的过程中,直接拆解出需要的结果字符串
解题思路如下:
- 初始化
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; }; 复制代码
至此我们就完成了 leetcode-1021-删除最外层的括号
如有任何问题或建议,欢迎留言讨论!