左右括号的最小处理次数
1、题目描述
多多君在处理一个由左结号(和右语号)组成的字符串,多多君每次处理时可以顺序读取一个字符或者一个有效括号子串,求问多多的最小处理次数。
输入描述:
第一行为一个整数N,表示字符串长度(1<=N<=10000),
第二行输入为一个长度为N的字符串,字符串由( 和 )组成
输出描述:
输出一个整数,表示字符串的最小处理次数
补充说明:
有效括号子串需要满足:
1.括号成对闭合,每个"("都有一个对应的")"
2.正确嵌套顺序:右括号不能出现在对应的左括号之前
例如:“()”,“()()”“(()())”均有效括号子串,“)(”, "(()","()())"不是有效括号
实例1:
输入:
4
))))
输出
4
说明
每个字符需要单独处理,需要处理4次
实例2:
输入:
6
((()))
输出:
1
说明
((()))为有效括号子串,需要处理1次
2、解题思路
要解决这个问题,我们需要找到处理给定括号字符串的最小次数。每次处理可以是一个单独的字符或一个有效的括号子串。有效括号子串的定义是成对闭合且正确嵌套的括号序列。
-
有效括号子串识别:利用栈来识别有效的括号子串。遍历字符串,遇到左括号时压栈,遇到右括号时弹出栈顶的左括号,并记录有效子串的位置。
-
处理次数计算:未被包含在任何有效子串中的字符需要单独处理。有效子串可以一次性处理,因此处理次数等于未被覆盖的字符数加上有效子串的数量。
代码实现
public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int N = scanner.nextInt();String s = scanner.next();System.out.println(minProcessingTimes(s));}public static int minProcessingTimes(String s) {Stack<Integer> stack = new Stack<>();boolean[] matched = new boolean[s.length()];// 标记所有匹配的括号对for (int i = 0; i < s.length(); i++) {if (s.charAt(i) == '(') { //遇到(就入栈stack.push(i);} else if (!stack.isEmpty()) { //遇到),且栈不为空,就弹出栈顶元素,并记录有效位置matched[stack.pop()] = true; //栈顶字符(的位置记为true,且)位置也记为truematched[i] = true;}}int count = 0;int i = 0;while (i < s.length()) {if (matched[i]) {count++; // 处理一个有效子串while (i < s.length() && matched[i]) {i++; // 跳过已匹配的字符}} else {count++; // 处理单个字符i++;}}return count;}
代码解释
-
栈的使用:遍历字符串,使用栈来匹配有效的括号对。遇到左括号时压栈,遇到右括号时弹出栈顶的左括号,并标记这两个位置为已匹配。
-
处理次数计算:遍历标记数组,连续的已匹配字符视为一个有效子串,只需一次处理;未匹配的字符需要单独处理。
-
时间复杂度:O(N),其中N是字符串的长度。每个字符仅被处理一次,栈操作也是线性时间。