删除最外层括号

基于括号差删除最外层括号

题目

(1)有效括号字符串为空 “”、"(" + A + “)” 或 A + B ,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。
(2)例如,"","()","(())()" 和 “(()(()))” 都是有效的括号字符串。
(3)如果有效字符串 s 非空,且不存在将其拆分为 s = A + B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。
(4)给出一个非空有效字符串 s,考虑将其进行原语化分解,使得:s = P_1 + P_2 + … + P_k,其中 P_i 是有效括号字符串原语。
(5)对 s 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 s 。
(6)示例如下
输入:s = “(()())(())”
输出:"()()()"
解释:
输入字符串为 “(()())(())”,原语化分解得到 “(()())” + “(())”,
删除每个部分中的最外层括号后得到 “()()” + “()” = “()()()”。

解决思路

  • 用cnt记录左右括号的差值,当遇到左括号时,cnt的值加1。当遇到右括号时,cnt的值减1。
  • cnt等于0的位置就是最外层括号的位置。当cnt等于0时,去除最外层括号,保留最外层括号内的子串,然后将所有子串拼接成一个字符串,即为答案。

代码

# include <stdio.h>
# include <string>

using namespace std;


class Solution {
public:
    string removeOuterParentheses(string s) {
        string ret;
        int cnt = 0;    // 记录左右括号的差值。
        int pre = 0;    // 记录当前括号序列的起始位置,如(()())的起始位置。

        for (int i = 0; i < s.size(); i++) {
            if ('(' == s[i]) {
                cnt += 1;   // 遇到左括号,cnt的值加1
            } else {
                cnt -= 1;   // 遇到右括号,cnt的值减1
            }

            // 当cnt=0时,去除最外层的括号(即只保留最外层括号内部的元素),通过子串截取实现
            if (0 == cnt) {
                // 子串的下标从pre + 1开始,长度为i - pre - 1
                ret += s.substr(pre + 1, i - pre - 1);
                pre = i + 1;    // 指向下一个括号序列的起点
            }
        }
        return ret;
    }
};


int main() {
    Solution *solution = new Solution();
    string s = "(()())(())";
    printf("%s\n", solution->removeOuterParentheses(s).c_str());
    return 0;
}
  • Python代码
# -*- coding: utf-8 -*-

class Solution:
    def __init__(self):
        pass

    def removeOuterParentheses(self, s: str) -> str:
        ret: str = ''
        cnt: int = 0        # 记录左右括号的差值。
        pre: int = 0        # 记录当前括号序列的起始位置,如(()())的起始位置。

        for i in range(len(s)):
            if '(' == s[i]:
                cnt += 1    # 遇到左括号,cnt的值加1
            else:
                cnt -= 1    # 遇到右括号,cnt的值减1

            # 当cnt=0时,去除最外层的括号(即只保留最外层括号内部的元素),通过切片取值实现
            # 子串的起始下标为pre + 1开始,结束下标为i - 1
            if 0 == cnt:
                ret += s[pre + 1: i]
                pre = i + 1     # 指向下一个括号序列的起点
        return ret


def main():
    solution = Solution()
    s = "(()())(())"
    print(solution.removeOuterParentheses(s))


if __name__ == "__main__":
    main()

说明

  • 对应LeetCode第1021题。
  • 链接:https://leetcode-cn.com/problems/remove-outermost-parentheses/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值