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:


Test Cases

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 = "))(("
Output: ""
Explanation: An empty string is also valid.

Solution

class Solution {
public:
    string minRemoveToMakeValid(string s) {
        stack<int> st;
        int n = s.length();
        for(int i=0; i<n; i++) {
            if (s[i] == '(') {
                st.push(i);
            } else if (s[i] == ')') {
                if (!st.empty()) {
                    st.pop();
                } else {
                    s[i] = '*';
                }
            }
        }
        while(!st.empty()) {
            s[st.top()] = '*';
            st.pop();
        }
        s.erase(remove(s.begin(), s.end(), '*'), s.end());
        return s;
    }
};
class Solution {
    public String minRemoveToMakeValid(String s) {
        StringBuilder builder = new StringBuilder(s);
        Deque<Integer> stack = new ArrayDeque<>();

        for(int i=0; i<s.length(); i++) {
            char c = s.charAt(i);
            if (c == '(') {
                stack.offerLast(i);
            } else if (c == ')') {
                if (!stack.isEmpty()) {
                    stack.pollLast();
                } else {
                    builder.setCharAt(i, '*');
                }
            }
        }

        while(!stack.isEmpty()) {
            builder.setCharAt(stack.pollLast(), '*');
        }

        return builder.toString().replace("*", "");
    }
}

/*
* Alternate approach without using stack
class Solution {
    public String minRemoveToMakeValid(String s) {
        StringBuilder sb = new StringBuilder(s);
        int open = 0;
        for(int i=0; i<s.length(); i++) {
            char c = s.charAt(i);
            if (c == '(') {
                open++;
            } else if (c == ')') {
                if (open > 0) {
                    open--;
                } else {
                    sb.setCharAt(i, '*');
                }
            }
        }

        int i = s.length() - 1;
        while(i >=0 && open > 0) {
            if (s.charAt(i) == '(') {
                sb.setCharAt(i, '*');
                open--;
            }
            i--;
        }

        return sb.toString().replace("*", "");
    }
}
*
* */
class Solution:
    def minRemoveToMakeValid(self, s: str) -> str:
        stack = []
        arr = list(s)
        print(arr)
        for i in range(len(s)):
            if s[i] == '(':
                stack.append(i)
            elif s[i] == ')':
                if not stack:
                    arr[i] = '*'
                else:
                    stack.pop()
        while stack:
            arr[stack.pop()] = '*'
        return ''.join(arr).replace('*', '')
Time Complexity: O(n)
Space Complexity: O(n)