【Leetcode】1249. Minimum Remove to Make Valid Parentheses

题目地址:

https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/

给定一个含括号的字符串 s s s(除了括号还可能含英文字母)。要求删去最少数量的括号,使得该字符串里的括号是合法的。返回任意删除括号后合法的字符串。

只需了解合法括号串的充分必要条件即可。一个括号串合法当且仅当:
1、任意前缀中左括号数大于等于右括号数;
2、全局来看左括号右括号数相等。
我们设计算法如下:用两个变量 l l l r r r分别记录遇到的左右括号数量。遍历 s s s,遇到非括号字符直接跳过,遇到左右括号时相应的计数加 1 1 1;如果发现 l < r ll<r,说明需要删右括号,将当前右括号的位置换成别的字符(java里可以先将 s s s转为char[]类型,再操作),同时将 r r r减去 1 1 1;遍历完整个字符串之后,如果 l > r l>r l>r,说明有 l − r l-r lr个左括号需要删除,此时我们选择删除最后出现的 l − r l-r lr个左括号,这样仍然能保证整个括号是合法的。代码如下:

public class Solution {
    public String minRemoveToMakeValid(String s) {
        int l = 0, r = 0;
        
        char[] str = s.toCharArray();
        for (int i = 0; i < str.length; i++) {
            if (str[i] != '(' && str[i] != ')') {
                continue;
            }
            
            if (str[i] == '(') {
                l++;
            } else {
                r++;
            }
            
            // 如果l < r,说明当前的右括号要删除,则标记其为空格
            if (l < r) {
                str[i] = ' ';
                r--;
            }
        }
     
     	// 算一下需要删除的左括号数量
        int del = l - r;
        
        StringBuilder sb = new StringBuilder();
        // 我们从后向前遍历,这样方便删除最后出现的del个左括号
        for (int i = str.length - 1; i >= 0; i--) {
            if (str[i] != ' ') {
                if (str[i] == '(' && del > 0) {
                    del--;
                }else {
                    sb.append(str[i]);
                }
            }
        }
        
        // 最后记得翻转回来
        return sb.reverse().toString();
    }
}

时空复杂度 O ( l s ) O(l_s) O(ls)

你可能感兴趣的:(LC,栈,队列,串及其他数据结构,字符串,数据结构,java,leetcode)