Leetcode刷题系列:删除最外层的括号 | 8月更文挑战

361 阅读2分钟

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

前言

之前就想参加6月的更文行动,但因为自身原因没能参加。8月 这次还是想来参加一下。希望能通过这次活动,慢慢的能养成输出的好习惯。并且不断的提升自身的水平,输出好的文章。也希望能结交更多的朋友。相互一起成长。

希望大家看到不足之处,多多点评!谢谢!

题目

有效括号字符串为空 ""、"(" + A + ")" 或 A + B ,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的连接。

例如,"","()","(())()" 和 "(()(()))" 都是有效的括号字符串。 如果有效字符串 s 非空,且不存在将其拆分为 s = A + B 的方法,我们称其为原语(primitive),其中 A 和 B 都是非空有效括号字符串。

给出一个非空有效字符串 s,考虑将其进行原语化分解,使得:s = P_1 + P_2 + ... + P_k,其中 P_i 是有效括号字符串原语。

对 s 进行原语化分解,删除分解中每个原语字符串的最外层括号,返回 s 。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re…

测试案例

实例1:

    输入:s = "(()())(())"
    输出:"()()()"

实例2:

    输入: s = "(()())(())(()(()))"
    输出: "()()()()(())"

方法一: 暴利破解(分解,循环在合并)

实现流程:

  1. 确认原语: 通过 计算 左右括号个数,当个数相同时,则括号内的字符串为原语
  2. 将原语 存储到新的数组中
  3. 循环遍历原语,去除最外层括号,并追加到字符串中

具体方式:

  • 创建一个 new ArrayList<>(), 用于存放原语
  • 定义 :
    • left = 0 左括号个数
    • right = 0 右括号个数
    • lastOpr = 0 原语字符串的最后位数
  • 循环遍历字符
    • 字符 == ‘(’ : left++
    • 字符 == ‘)’ : right++
    • 当 left == right 则表明 是原语,截取字符串,存储原语数组中
  • 遍历 原语数组
    • 截取字符串 并追加到字符串中

代码

public String test1(String s) {
    // 暴利破解
    int len = s.length();
    List<String> strings = new ArrayList<String>();

    int left = 0, right = 0, lastOpr = 0;
    for (int i = 0; i < len; i++) {
        char c = s.charAt(i);
        if (c == '(') {
            left++;
        } else if (c == ')') {
            right++;
        }
        if (left == right) {
            strings.add(s.substring(lastOpr, i + 1));
            lastOpr = i + 1;
        }
    }

    StringBuilder stringBuilder = new StringBuilder();
    for (String string : strings) {
        stringBuilder.append(string.substring(1, string.length() - 1));
    }
    return stringBuilder.toString();
}

方法二: 暴利破解 (定位后,直接合并)

优化点: 去除原语数组,在获取到原语字符串后,直接删除原语最外层括号,并存入数组中


public String test2(String s) {
    int len = s.length();
    StringBuilder stringBuilder = new StringBuilder();
    int left = 0, right = 0, lastOpr = 0;
    for (int i = 0; i < len; i++) {
        char c = s.charAt(i);
        if (c == '(') {
            left++;
        } else if (c == ')') {
            right++;
        }
        if (left == right) {
            stringBuilder.append(s.substring(++lastOpr, i));
            lastOpr = i + 1;
        }
    }
    return stringBuilder.toString();
}

方法三: 使用 计数器 方式

通过 整型字段(count) 计算 括号数 ,出现一个 左括号 + 1 , 一个 右括号 -1

实现流程:

  • 核心点:
  • 当 字符 等于 左括号时:
    • 先进行判断 count > 0 ,即字符是原语内有效的字符 ,将字符存储到新字符串中
    • 在进行 计数值 进行累加 count++
  • 当 字符 等于 右括号时:
    • 先进行 计算值 递减 count—
    • 在进行判断 count > 0 , 即字符是原语内有效的字符 ,将字符存储到新字符串中
public String arrayNumsTest(String s) {
    StringBuilder stringBuilder = new StringBuilder();
    int count = 0;
    int len = s.length();
    char[] chars = s.toCharArray();
    for (int i =0 ; i<len; i++) {
        char c = chars[i];
        if (c == '(') {
            if (count > 0) {
                stringBuilder.append(c);
            }
            count++;
        } else {
            count--;
            if (count > 0) {
                stringBuilder.append(c);
            }
        }
    }
    return stringBuilder.toString();

}