1249

difficulty: Medium

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 <= 10^5

  • s[i] is one of '(' , ')' and lowercase English letters.

这个题要注意和301的区别。 301 要求的是所有的 minRemove 的结果 这个只需要找到其中的一个结果就好了。 区别在于,找到其中的一个结果,可以用好几种不同的算法。

Method One

class Solution {
    public String minRemoveToMakeValid(String s) {
        int netCount = 0;
        LinkedList<Integer> indices = new LinkedList<>();

for(int i = 0; i < s.length(); i++) {
           char c = s.charAt(i);
           if( c == '(' ) {
               indices.push(i);
               netCount += 1;
          }
           if( c == ')' ) {
               if( netCount > 0) {
                   netCount -= 1;
                   indices.pop();
              }else {
                   indices.push(i);
              }
          }
      }
       StringBuilder ans = new StringBuilder();
       Set<Integer> indicesSet = new HashSet<Integer>();
       int sizeOfIndices = indices.size();

for( int i = 0; i < sizeOfIndices; i++ ) {
           indicesSet.add(indices.pop());
      }
       for( int i = 0; i < s.length(); i++) {
           char c = s.charAt(i);
           if(indicesSet.contains(i)) {

continue;
          }
           ans.append(c);
      }
       return String.valueOf(ans);
  }

//不用以下的办法是因为 substring 是 O(N);
   // public String removeIth(String s, int i) {
   //     return s.substring( 0 , i ) + s.substring( i + 1 );
   // }
}

Method

以下是一个自己想的方法。原理大致相同。 这个题,O(N) 的解法,扫两遍数组是必须的。

class Solution {
    public String minRemoveToMakeValid(String s) {
        int counter = 0;
        StringBuilder sb = new StringBuilder();
        LinkedList<Integer> leftParenthesesIndices = new LinkedList<>();
        int i = 0;
        while( i < s.length() ){
            if(s.charAt(i) == '('){
                counter += 1;
                leftParenthesesIndices.push(sb.length());
            }
            if(s.charAt(i) == ')'){
                counter -= 1;
                if( counter < 0){
                    i++;
                    counter = 0;
                    continue;
                }
            }
            sb.append(s.charAt(i));
            i++;
        }

        while( counter > 0 ){
            sb.deleteCharAt(leftParenthesesIndices.pop());
            counter--;
        }
        return sb.toString();
    }
}

Method Best!


class Solution {

    public String minRemoveToMakeValid(String s) {

        // Parse 1: Remove all invalid ")"
        StringBuilder sb = new StringBuilder();
        int openSeen = 0;
        int balance = 0;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == '(') {
                openSeen++;
                balance++;
            } if (c == ')') {
                if (balance == 0) continue;
                balance--;
            }
            sb.append(c);
        }

        // Parse 2: Remove the rightmost "("
        StringBuilder result = new StringBuilder();
        int openToKeep = openSeen - balance;
        for (int i = 0; i < sb.length(); i++) {
            char c = sb.charAt(i);
            if (c == '(') {
                openToKeep--;
                if (openToKeep < 0) continue;
            }
            result.append(c);
        }

        return result.toString();
    }
}

Last updated

Was this helpful?