Problem
A parentheses string is valid if and only if:
- It is the empty string,
- It can be written as
AB
(A
concatenated withB
), whereA
andB
are valid strings, or - It can be written as
(A)
, whereA
is a valid string.
You are given a parentheses string s
. In one move, you can insert a parenthesis at any position of the string.
- For example, if
s = "()))"
, you can insert an opening parenthesis to be"(()))"
or a closing parenthesis to be"())))"
.
Return the minimum number of moves required to make s
valid.
Examples
Example 1:
Input: s = "())"
Output: 1
Example 2:
Input: s = "((("
Output: 3
Solution
Video explanation
Here is the video explaining below methods in detail. Please check it out:
Method 1 - Using Stack
Loop through the input array, and initialize the stack and left counter signifying number of left parenthesis required:.
- If we encounter ‘(’, push ‘(’ into stack;
- otherwise, ‘)’, check if there is a matching ‘(’ on top of stack; if no, increase the left counter by 1; if yes, pop it out;
- after the loop, count in the un-matched characters remaining in the stack.
Code
Java
public class Solution {
public int minAddToMakeValid(String s) {
// Initialize a stack to keep track of unmatched opening parentheses
Deque<Character> stk = new ArrayDeque<>();
// Initialize a counter to count the unmatched closing parentheses
int left = 0;
// Traverse each character in the string
for (char ch : s.toCharArray()) {
if (ch == '(') {
// If it's an opening parenthesis, push it onto the stack
stk.push(ch);
} else if (!stk.isEmpty()) {
// If it's a closing parenthesis and there's a matching opening parenthesis in the stack, pop the stack
stk.pop();
} else {
// If it's a closing parenthesis with no matching opening parenthesis, increment the left counter
left++;
}
}
// The total needed moves to make the string valid are the sum of the unmatched closing parentheses (left)
// and the unmatched opening parentheses (remaining elements in the stack)
return left + stk.size();
}
}
Python
class Solution:
def minAddToMakeValid(self, s: str) -> int:
stack = []
left = 0
for ch in s:
if ch == '(':
stack.append(ch)
elif stack:
stack.pop()
else:
left += 1
return left + len(stack)
Complexity
- ⏰ Time complexity:
O(n)
, wheren
is the length of the strings
, because we process each character exactly once. - 🧺 Space complexity:
O(n)
Method 2 - Track left and right bracket needed
Here is the approach:
Understanding Valid Parentheses:
- A valid parentheses string must balance every opening parenthesis
'('
with a closing parenthesis')'
.
- A valid parentheses string must balance every opening parenthesis
Count Imbalance:
- Traverse the string
s
, maintaining a count of open and close braces. - An imbalance occurs when there are more closing parentheses
')'
than opening parentheses'('
at any point.
- Traverse the string
Calculate Minimum Moves:
- Use a counter to track the number of moves to balance open and close parentheses.
- As you traverse the string:
- If a mismatch is detected (more
')'
than'('
), increment the counter. - At the end of traversal, the count of unbalanced opening parentheses also needs to be accounted for in the result.
- If a mismatch is detected (more
Code
Java
public class Solution {
public int minAddToMakeValid(String s) {
int left = 0; // Track needed opening parentheses
int right = 0; // Track needed closing parentheses
for (char ch : s.toCharArray()) {
if (ch == '(') {
right++; // Increase closing parenthesis needed
} else if (right > 0) {
right--; // One closing parenthesis matched
} else {
left++; // Extra closing parenthesis found
}
}
// Total needed valid moves are the sum of left and right
return left + right;
}
}
Python
class Solution:
def minAddToMakeValid(self, s: str) -> int:
left = 0 # Track needed opening parentheses
right = 0 # Track needed closing parentheses
for char in s:
if char == '(':
right += 1 # Increase closing parenthesis needed
elif right > 0:
right -= 1 # One closing parenthesis matched
else:
left += 1 # Extra closing parenthesis found
# Total needed valid moves are the sum of left and right
return left + right
Complexity
- ⏰ Time complexity:
O(n)
, because we process each character exactly once. - 🧺 Space complexity:
O(1)
- , since we use a few additional variables to keep track of the counters for the needed parentheses, and no additional data structures are used.