03删除最外层括号1021

03删除最外层括号1021

1.Comprehend 理解题意

给出一个非空有效字符串S,考虑将其进行原语化分解。 使得:S=P_1+P_2+…+P_k,其中P_i是有效括号字符串原语。 对S进行原语化分解,删除分解中每个原语字符串的最外层括号,返回S。

➢ 有效括号字符串:例如:“( )”,“( ( ) ) ( )” 和 “( ( ) ( ( ) ) )”

➢ 原语:如果有效字符串S非空,且不能将其拆分为 S =A+B,我们称其为原语(primitive), 其中A和B都是非空有效括号字符串。

题目基本信息

  • 有效括号字符串:括号必然成对出现
  • 给定字符串 S 非空,但返回结果可能为空
  • 原语化分解只需要进行一级
  • 返回删除每个原语的最外层括号后的字符串

附加信息

  • S.length <= 10000
  • S[i]为"(“或”)"

解法一:暴力解法

  • 先分解成字符串原语
  • 再删除每部分最外层括号
  • 返回各部分合并后的结果

解法二:优化解法

  • 对原字符串进行原语识别
  • 获取不包含最外层括号的子串
  • 将各部分拼接返回

2.Choose 数据结构及算法思维选择

解法一:分解、删除再合并

  • 数据结构:字符串、数组
  • 算法思维:遍历、计数器、累加

解法一:暴力解法思路分析

  1. 定义容器存储原语子串 new ArrayList();
  2. 定义左括号、右括号计数器: int left = 0, right = 0;
  3. 遍历字符串,读取到括号时对应计数器自增
  4. 检查是否到达原语结尾,截取原语子串并添加 到容器中
  5. 遍历容器,删除最外层括号后合并成新串

解法一:边界和细节问题

  1. 边界问题:

遍历字符串,注意索引越界:i < S.length() 截取原语字符串时,注意起止索引:[start, end)

  1. 细节问题:

需要记录上一次截取原语子串之后的位置 删除原语子串的最外层括号,其实就是重新截取

解法一:代码

  class Solution {
      public String removeOuterParentheses(String s) {
          char[] chars = s.toCharArray();
          int length = chars.length;
          int leftCount = 0, rightCount = 0, primitiveStart = 0;
          List<String> primitives = new ArrayList<>();
          for (int i = 0; i < length; i++) {
              char aChar = chars[i];
              if (aChar == '(') {
                  leftCount++;
              } else if (aChar == ')') {
                  rightCount++;
              }
              if (leftCount == rightCount) {
                  primitives.add(s.substring(primitiveStart, i + 1));
                  primitiveStart = i + 1;
              }
          }
          StringBuilder result = new StringBuilder();
          for (String primitive : primitives) {
              result.append(primitive.substring(1,primitive.length()-1));
          }
          return result.toString();
      }
  }

解法二:优化解法思路分析

  1. 定义容器存储删除外层括号后的原语子串 new StringBuilder();
  2. 定义左括号、右括号计数器: int left = 0, right = 0;
  3. 遍历字符串,读取到括号时对应计数器自增
  4. 检查是否到达原语结尾,截取不包含最外层的 原语子串并拼接到容器中

解法二代码

class Solution {
    public String removeOuterParentheses(String s) {
        char[] chars = s.toCharArray();
        int length = chars.length;
        StringBuilder result = new StringBuilder();
        int leftCount = 0, rightCount = 0, primitiveStart = 0;
        for (int i = 0; i < length; i++) {
            char aChar = chars[i];
            if (aChar == '(') {
                leftCount++;
            } else /*if (aChar == ')')*/ {
                rightCount++;
            }
            if (leftCount == rightCount) {
                result.append(s.substring(primitiveStart + 1, i));
                primitiveStart = i + 1;
            }
        }
        return result.toString();
    }
}

4.Consider 思考更优解

  1. 剔除无效代码或优化空间消耗
  • 只需要一个计数器:"(“自增,”)"自减
  • 如果字符串数据只是两两配对怎么处理?
  • 有没有一种支持后进先出的数据结构?
  1. 寻找更好的算法思维 • 借鉴其它算法

关键知识点:栈(Stack)

  • 限定仅在表尾进行插入和删除操作的线性表
  • 栈顶(Top):操作数据的一端,即表尾
  • 栈底(Bottom):线性表的另一端,即表头
  • 特点:LIFO(Last In First Out),后进先出
  • 基本操作:
    • 进栈:push(),在栈顶插入元素,入栈、压栈 • 出栈:pop(),从栈顶删除数据
    • 判断空:isEmpty()

在这里插入图片描述

5.Code 最优解思路及编码实现

最优解:栈解法

  1. 使用数组模拟一个栈,临时存储字符,替代计数器

    • push(Character) ; pop(); isEmpty()
  2. 遍历字符串,根据情况进行入栈/出栈操作

    • 读取到左括号,左括号入栈
    • 读取到右括号,左括号出栈
  3. 判断栈是否为空,若为空,找到了一个完整的原语

  4. 截取不含最外层括号的原语子串并进行拼接

最优解:边界和细节问题

  1. 边界问题:

遍历字符串,注意索引越界:i < S.length() 截取原语字符串时,注意起止索引:[start, end)

  1. 细节问题:

需要记录上一次截取原语子串之后的位置 右括号无需进栈

最优解代码

class Solution {
    public String removeOuterParentheses(String s) {
        StringBuilder result = new StringBuilder();
        char[] chars = s.toCharArray();
        int length = chars.length;
        int stackCount = 0;
        for (int i = 0; i < length; i++) {
            char aChar = chars[i];
            if (aChar == '(') {
                stackCount++;
                if (stackCount > 1) {
                    result.append(aChar);
                }
            } else {//aChar = ')'
                stackCount--;
                if (stackCount > 0) {
                    result.append(aChar);
                }
            }
        }
        return result.toString();
    }
}

6.Change 变形延伸

题目变形

  • (练习)删除最内层的括号
  • (练习)用链表实现一个栈(链栈)

延伸扩展

  • 逆波兰表达式求值:给定数字和运算符,根据规则计算出结果
  • 子程序调用:方法依次进栈,最后调用的最先结束
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
如果你的意思是将JSON字符串最外层的大括号删除,可以使用字符串切片或者正则表达式来实现。以下是一个示例代码,演示如何删除JSON字符串最外层的大括号: 方法一:使用字符串切片 ```python import json # JSON数据 json_data = '{"name": "Alice", "age": 25}' # 删除外层的大括号 json_data_new = json_data[1:-1] # 将JSON数据转换为Python对象 python_obj = json.loads(json_data_new) print(python_obj) # 输出结果:{"name": "Alice", "age": 25} ``` 在这个示例中,我们使用字符串切片将JSON字符串最外层的大括号删除,然后将结果转换为Python对象`python_obj`。输出结果为`{"name": "Alice", "age": 25}`,可以看到最外层的大括号已经被删除了。 方法二:使用正则表达式 ```python import re import json # JSON数据 json_data = '{"name": "Alice", "age": 25}' # 删除外层的大括号 json_data_new = re.sub(r'^\{|\}$', '', json_data) # 将JSON数据转换为Python对象 python_obj = json.loads(json_data_new) print(python_obj) # 输出结果:{"name": "Alice", "age": 25} ``` 在这个示例中,我们使用正则表达式将JSON字符串最外层的大括号删除,然后将结果转换为Python对象`python_obj`。输出结果为`{"name": "Alice", "age": 25}`,可以看到最外层的大括号已经被删除了。请注意,这种方法只适用于最外层是大括号的情况,如果你的JSON字符串最外层是其他类型的括号,需要相应地修改正则表达式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pirmingham

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值