删除最外层的括号

281 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

一、题目

LettCode 删除最外层的括号

有效括号字符串为空 ""、"(" + 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 是一个有效括号字符串

二、题解

简单的说就是需要删除每个部分的外层大括号即可,每个部分都是有效括号,并且不能再拆分成两个有效括号。

方法一

给定的字符串中的原语,也就是每一个部分都是有效的括号,所以括号都是成对的,也就是是字符'('和字符')'数量的一样的,所以我们可以记录字符'('和字符')'的数量,当字符'('和字符')'的数量相等的时候就是一个部分即原语,我们只需要获取这个区间内除两边的括号外的字符就可以了。具体的我们需要遍历一次字符串的每一个字符,当遇到字符'('的时间计数变量count就加1,当遇到字符')'的时候计数变量count就减1,当count为0的时候就是一个原语了,获取一个原语最开始的字符时count是0,获取最后的字符时count也是0,因此当count不为0的时候获取的字符都是我们需要返回的。

方法二

同样的可以使用栈来记录括号,首先遍历字符串的字符,当遇到字符'('的时候将字符'('加入栈里面,当遇到字符')'的时候就将栈里的一个字符'('弹出,这样就完成了一次括号的匹配,而对于每一个原语,其都是一个最小不可分割的有效括号,那其字符'('和字符')'的数量是相等的,所以当栈元素为空的时候就是一个原语的分割点,初始的栈为空就是一个原语的起点,遍历完一个原语后栈也为空,同时也是下一个原语的起点(如果有下一个的话),因此当栈不为空的时候,遍历获取的字符就是我们需要拼接返回的。

三、代码

方法一 Java代码

class Solution {
    public String removeOuterParentheses(String s) {
        int count = 0;
        StringBuilder parentheses = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == ')') {
                count--;
            }
            if (count > 0) {
                parentheses.append(c);
            }
            if (c == '(') {
                count++;
            }
        }
        return parentheses.toString();
    }
}

时间复杂度:O(n),需要遍历一次字符串的所有字符。

空间复杂度:O(n),需要截取字符串占用的空间。


方法二 Java代码

class Solution {
    public String removeOuterParentheses(String s) {
        Deque<Character> deque = new ArrayDeque<Character>();
        StringBuilder parentheses = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == ')') {
                deque.pop();
            }
            if (!deque.isEmpty()) {
                parentheses.append(c);
            }
            if (c == '(') {
                deque.push(c);
            }
        }
        return parentheses.toString();
    }
}

时间复杂度:O(n),需要遍历一次字符串的所有字符。

空间复杂度:O(n),需要截取字符串占用的空间,以及使用栈空间存储括号。