27-leetCode: 1021. 删除最外层的括号

107 阅读2分钟

题目

有效括号字符串为空 ""、"(" + 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 = "(()())(())"
输出:"()()()"
解释:
输入字符串为 "(()())(())",原语化分解得到 "(()())" + "(())",
删除每个部分中的最外层括号后得到 "()()" + "()" = "()()()"

解题思路

不难看出,本题的思路是把有效括号拆分成n个外层括号,然后取括号内的值拼接起来。既然每部分是有效括号,那么必然的左括号的数量等于右括号的数量,所以可以定义一个count值,遇到左括号+1, 遇到右括号-1,当count为0 时,表示找到了一部分,同时定义start为左括号起始位置,当count为0 时,循环的i值就是一对有小括号的终点,此时截取start+1 => i的值, 同时令start = i + 1 ;开始下一部分的取值,最后将结果拼接返回

/**
 * @param {string} s
 * @return {string}
 */
var removeOuterParentheses = function(s) {
    // 定义结果字符串, 记录左右括号值count和需要截取的起始位置start
    let result = '', count = 0, start = 0;
    for(let i = 0; i < s.length; i++) {
        if (s[i] === '(') {
            count++;
        } else {
            count--;
            // count为0 说明找到了其中的一部分
            if(count === 0) {
                // 拼接字符串
                result += s.substring(start + 1, i);
                // 开始下一部分的查找
                start = i + 1;
            }
        }
    }
    // 结果是拼接后的字符串
    return result;
};