32. Longest Valid Parentheses - Detailed Explanation
Problem Statement
Description:
Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
Examples:
-
Example 1:
- Input:
"(()" - Output:
2 - Explanation: The longest valid substring is
"()".
- Input:
-
Example 2:
- Input:
")()())" - Output:
4 - Explanation: The longest valid substring is
"()()".
- Input:
-
Example 3:
- Input:
"" - Output:
0 - Explanation: An empty string has no valid substrings.
- Input:
Constraints:
- The length of the input string can be zero.
- The string consists only of the characters
'('and')'.
Hints for the Solution
-
Hint 1:
Think about what makes a parentheses string valid. A valid substring has every opening parenthesis'('matched with a closing parenthesis')'in the correct order. -
Hint 2:
One efficient approach is to use a stack to track the indices of unmatched parentheses. This helps you quickly determine the length of valid segments when a match is found.
Approaches to Solve the Problem
1. Brute Force Approach
Idea:
Check every possible substring and validate if it is a well-formed parentheses string. Then, record the length of the valid ones.
Steps:
- Generate all possible substrings.
- For each substring, check whether it forms a valid sequence.
- Track the maximum length found.
Downside:
- This approach is very inefficient with a time complexity of O(n³) (generating substrings and validating each one), which is not feasible for large inputs.
2. Dynamic Programming Approach
Idea:
Use a DP array where dp[i] represents the length of the longest valid substring ending at index i.
Steps:
- Initialize a DP array of size
n(length of the string) with all zeros. - Iterate through the string from index 1 to n-1.
- If the character at
iis')':- Case 1: If the previous character is
'(', thendp[i] = dp[i-2] + 2. - Case 2: If the previous character is also
')'and the character at the positioni - dp[i-1] - 1is'(', thendp[i] = dp[i-1] + 2plus any valid substring ending before that (i.e.dp[i - dp[i-1] - 2]).
- Case 1: If the previous character is
- Keep track of the maximum value in the DP array.
Complexity:
- Time Complexity: O(n)
- Space Complexity: O(n)
3. Stack-Based Approach
Idea:
Use a stack to store indices of the characters. Begin by pushing -1 onto the stack as a base index. Then iterate over the string and:
- Push the current index if the character is
'('. - For a
')', pop an index from the stack.- If the stack becomes empty, push the current index as a new base.
- Otherwise, calculate the valid substring length as the difference between the current index and the top of the stack.
Steps:
- Initialize a stack with
-1. - Loop through the string by index:
- If
s[i]is'(', pushi. - If
s[i]is')', pop from the stack.- If the stack is empty, push
i. - Otherwise, update the maximum length as
i - stack.top().
- If the stack is empty, push
- If
- The maximum length recorded is the answer.
Complexity:
- Time Complexity: O(n)
- Space Complexity: O(n)
4. Two-Pointer Approach
Idea:
Use two counters (left and right) to scan the string twice: once from left to right and then from right to left.
Steps:
- Left-to-Right Pass:
- Increment
leftfor'('andrightfor')'. - When
leftequalsright, update the maximum length. - If
rightbecomes greater thanleft, reset both counters.
- Increment
- Right-to-Left Pass:
- Do the reverse (increment counters accordingly).
- When
leftequalsright, update the maximum length. - If
leftexceedsright, reset both counters.
Note:
This approach is useful in cases where the valid sequence may be interrupted by more unmatched opening parentheses at the beginning.
Complexity:
- Time Complexity: O(n)
- Space Complexity: O(1)
Code Implementations
Python Implementation
Java Implementation
Complexity Analysis
-
Time Complexity:
For the stack-based and two-pointer approaches, we scan the string once (or twice in the case of two pointers), leading to O(n) time complexity. -
Space Complexity:
- The stack-based approach uses extra space for the stack, which in the worst case can be O(n).
- The two-pointer approach uses constant extra space, O(1).
Common Mistakes and Edge Cases
Common Mistakes:
-
Not Resetting the Base Index:
When the stack becomes empty (i.e., an unmatched closing parenthesis is encountered), failing to reset the base index can lead to incorrect length calculations. -
Ignoring Edge Cases:
Not handling an empty string or a string with only one type of parenthesis properly.
Edge Cases:
-
Empty String:
The input""should return0. -
All Open or All Close:
For strings like"(((("or"))))", the output should be0because no valid substring exists. -
Nested Valid Substrings:
Proper handling when valid substrings are nested or interleaved, e.g.,"()(())".
Additional Related Problems for Further Practice:
-
Valid Parentheses:
Check if a given string with multiple types of brackets is valid. -
Minimum Remove to Make Valid Parentheses:
Remove the minimum number of parentheses to make a string valid. -
Longest Common Substring:
Find the longest substring common to two strings. -
Longest Valid Parentheses Variation:
Explore problems that require similar validation and segmentation techniques.
GET YOUR FREE
Coding Questions Catalog
$197

$78
$78