Solution For Minimum Remove To Make Valid Parentheses
Problem Statement:
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.
Solution:
To solve this problem, we can use a stack data structure to keep track of the opening parentheses ‘(‘ that we have encountered. Whenever we encounter a closing parentheses ‘)’ and there is an opening parentheses at the top of the stack, we remove the opening parentheses from the stack and continue. If we encounter a closing parentheses and the stack is empty, we add this parentheses to a list of invalid parentheses indices.
After iterating through the entire string, we can remove all the parentheses at the indices in the list of invalid parentheses indices.
Here is the step-by-step algorithm:
Initialize a stack and a list to keep track of the invalid parentheses indices.
Iterate through the string s and for each character, do the following:
- If the character is an opening parentheses ‘(‘, push it onto the stack.
- If the character is a closing parentheses ‘)’, and the stack is not empty, pop the opening parentheses from the top of the stack and continue.
- If the character is a closing parentheses ‘)’ and the stack is empty, add the index of this parentheses to the list of invalid parentheses indices.
If the character is neither an opening or closing parentheses, continue.
After iterating through the entire string, remove all the parentheses at the indices in the list of invalid parentheses indices.
Return the updated string.
Here is the implementation of the above algorithm in Python:
def minRemoveToMakeValid(s: str) -> str:
stack = []
invalid_indices = []
for i, c in enumerate(s):
if c == '(':
stack.append(i)
elif c == ')':
if stack:
stack.pop()
else:
invalid_indices.append(i)
# Add any remaining opening parentheses to the list of invalid indices
invalid_indices += stack
# Remove the invalid parentheses from the string
result = ''
for i, c in enumerate(s):
if i not in invalid_indices:
result += c
return result
Time Complexity:
The time complexity of this algorithm is O(n), where n is the length of the input string. This is because we iterate through the string once, and all the stack operations are constant time operations.
Space Complexity:
The space complexity of this algorithm is also O(n), where n is the length of the input string. This is because we use a stack and a list to keep track of the invalid parentheses indices, and the size of these data structures is proportional to the length of the input string.
Step by Step Implementation For Minimum Remove To Make Valid Parentheses
class Solution { public String minRemoveToMakeValid(String s) { StringBuilder sb = new StringBuilder(s); Stackstack = new Stack<>(); for (int i = 0; i < sb.length(); i++) { if (sb.charAt(i) == '(') { stack.push(i); } if (sb.charAt(i) == ')') { if (!stack.isEmpty()) { stack.pop(); } else { sb.setCharAt(i, '*'); } } } while (!stack.isEmpty()) { sb.setCharAt(stack.pop(), '*'); } return sb.toString().replaceAll("\\*", ""); } }
def minRemoveToMakeValid(s): stack = [] to_remove = set() # First, we go through the string and push any "(" onto a stack. # For every ")", we check if the stack is empty. If it is, we add # the index of the ")" to our to_remove set. If it's not empty, we # pop the last element off the stack. for i, char in enumerate(s): if char == "(": stack.append(i) elif char == ")": if not stack: to_remove.add(i) else: stack.pop() # Next, we add any indices remaining in the stack to our to_remove set, # as they are unbalanced "(" that will never have a ")" to match them. to_remove = to_remove.union(set(stack)) # Finally, we build our output string, only adding characters at indices # that are not in our to_remove set. output = "" for i, char in enumerate(s): if i not in to_remove: output += char return output
var minRemoveToMakeValid = function(s) { let stack = []; let res = ""; for (let i = 0; i < s.length; i++) { if (s[i] === "(") { stack.push(i); } else if (s[i] === ")") { if (stack.length === 0) { res += s[i]; } else { stack.pop(); } } else { res += s[i]; } } while (stack.length > 0) { let idx = stack.pop(); res = res.slice(0, idx) + res.slice(idx + 1); } return res; };
The solution below removes the minimum number of parentheses needed to make the input string valid. First, we initialize a stack. We then iterate through the input string. For each character, we push it onto the stack if it's an open parentheses, and we pop off the top character of the stack if it's a close parentheses. If the stack is ever empty and we encounter a close parentheses, we know we need to remove that character. At the end, we iterate through the stack and remove all the open parentheses. This leaves us with only the characters we need to remove in order to make the input string valid.
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. public class Solution { public string MinRemoveToMakeValid(string s) { // create a stack to store the indices of '(' Stackstack = new Stack (); // create a set to store the indices that need to be removed HashSet set = new HashSet (); for(int i = 0; i < s.Length; i++){ // if we encounter an open parentheses, push the index to the stack if(s[i] == '('){ stack.Push(i); } // if we encounter a closed parentheses else if(s[i] == ')'){ // if the stack is empty, then this closed parentheses doesn't have a corresponding open parentheses, so add the index to the set if(stack.Count == 0){ set.Add(i); } // otherwise, pop the top element from the stack (which is the index of the most recent open parentheses) and continue else{ stack.Pop(); } } } // after we finish iterating through the string, if the stack is not empty, that means there are open parentheses that don't have a corresponding closed parentheses, so we add those indices to the set while(stack.Count != 0){ set.Add(stack.Pop()); } // create a new string builder StringBuilder sb = new StringBuilder(); // iterate through the original string for(int i = 0; i < s.Length; i++){ // if the current index is not in the set, append the character at that index to the string builder if(!set.Contains(i)){ sb.Append(s[i]); } } // convert the string builder to a string and return it return sb.ToString(); } }