1249. Minimum Remove to Make Valid Parentheses

Created: 09/26/2021

Leetcode

Given a string s of '(' , ')' and lowercase English characters.

Your task is to remove the minimum number of parentheses ( '(' or ')', in any positions ) so that the resulting parentheses string is valid and return any valid string.

Formally, a parentheses string is valid if and only if:

  • It is the empty string, contains only lowercase characters, or

  • It can be written as AB (A concatenated with B), where A and B are valid strings, or

  • It can be written as (A), where A is a valid string.

Example 1:

Input: s = "lee(t(c)o)de)"
Output: "lee(t(c)o)de"
Explanation: "lee(t(co)de)" , "lee(t(c)ode)" would also be accepted.

Example 2:

Input: s = "a)b(c)d"
Output: "ab(c)d"

Example 3:

Input: s = "))(("
Output: ""
Explanation: An empty string is also valid.

Example 4:

Input: s = "(a(b(c)d)"
Output: "a(b(c)d)"

Constraints:

  • 1 <= s.length <= 105

  • s[i] is either'(' , ')', or lowercase English letter.

Basic Idea:

当括号invalid的时候只有两种情况,一是出现了超过左括号的右括号,二是在结尾处右括号不足,导致有剩余的左括号没有被匹配。

对于第一种情况,我们可以在扫描的过程中动态记录leftCount-rightCount的值,一旦其变为负值,则当前的右括号就需要被删掉。

对于第二种情况,我们可以使用一个stack来记录左括号的index,如果遇到右括号则将其和前一个左括号抵消,最终剩下的左括号都需要删掉。

这道题目问的是最少需要被删掉的括号,容易让人多想,其实只需要删掉需要删掉的括号就好了。

Java Code:

class Solution {
    public String minRemoveToMakeValid(String s) {
        Deque<Integer> stack = new ArrayDeque<>();
        int leftCount = 0;
        Set<Integer> removeIndices = new HashSet<>();
        for (int i = 0; i < s.length(); ++i) {
            if (s.charAt(i) == '(') {
                leftCount++;
                stack.offerFirst(i);
            } else if (s.charAt(i) == ')') {
                if (leftCount == 0) {
                    removeIndices.add(i);
                } else {
                    leftCount--;
                    stack.pollFirst();
                }
            }
        }
        removeIndices.addAll(stack);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); ++i) {
            if (!removeIndices.contains(i)) {
                sb.append(s.charAt(i));
            }
        }
        return sb.toString();
    }
}

Last updated