左右括号的最小处理次数

1、题目描述

多多君在处理一个由左结号(和右语号)组成的字符串,多多君每次处理时可以顺序读取一个字符或者一个有效括号子串,求问多多的最小处理次数。


输入描述:

第一行为一个整数N,表示字符串长度(1<=N<=10000),
第二行输入为一个长度为N的字符串,字符串由( 和 )组成


输出描述:

输出一个整数,表示字符串的最小处理次数

补充说明:

有效括号子串需要满足:
1.括号成对闭合,每个"("都有一个对应的")"
2.正确嵌套顺序:右括号不能出现在对应的左括号之前
例如:“()”,“()()”“(()())”均有效括号子串,“)(”, "(()","()())"不是有效括号


实例1:

输入:
4
))))
输出
4
说明
每个字符需要单独处理,需要处理4次


实例2:

输入:
6
((()))
输出:
1
说明
((()))为有效括号子串,需要处理1次
 

 2、解题思路

要解决这个问题,我们需要找到处理给定括号字符串的最小次数。每次处理可以是一个单独的字符或一个有效的括号子串。有效括号子串的定义是成对闭合且正确嵌套的括号序列。

  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 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,且)位置也记为true
                matched[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;
    }

代码解释

  1. 栈的使用:遍历字符串,使用栈来匹配有效的括号对。遇到左括号时压栈,遇到右括号时弹出栈顶的左括号,并标记这两个位置为已匹配。

  2. 处理次数计算:遍历标记数组,连续的已匹配字符视为一个有效子串,只需一次处理;未匹配的字符需要单独处理。

  3. 时间复杂度:O(N),其中N是字符串的长度。每个字符仅被处理一次,栈操作也是线性时间。

你可能感兴趣的:(算法,java,字符串,栈)