32. Longest Valid Parentheses - Detailed Explanation

Free Coding Questions Catalog
Boost your coding skills with our essential coding questions catalog. Take a step towards a better tech career now!

Problem Statement

You are given a string containing just the characters '(' and ')'. Your task is to find the length of the longest valid (well-formed) parentheses substring.

Example 1

  • Input: "(()"
  • Output: 2
  • Explanation: The longest valid parentheses substring is "()".

Example 2

  • Input: ")()())"
  • Output: 4
  • Explanation: The longest valid parentheses substring is "()()".

Example 3

  • Input: ""
  • Output: 0
  • Explanation: The string is empty, so there is no valid substring.

Constraints:

  • The length of the string is between 0 and a large number (e.g., 30000).
  • The string consists only of the characters '(' and ')'.

Hints

  1. Stack Hint:
    Think about using a stack to store indices. This can help you determine the start of a valid substring when you encounter a closing parenthesis.

  2. Dynamic Programming Hint:
    Consider using a DP array where each element represents the length of the longest valid substring ending at that index. Update this array based on previous computations.

Approaches

Brute Force Approach

  • Idea:
    Check every possible substring and verify if it is valid by using a stack or a counter.

  • Steps:

    1. Generate all possible substrings.
    2. For each substring, check if it forms a valid parentheses sequence.
    3. Keep track of the maximum valid length found.
  • Complexity:

    • Time: O(n³) (O(n²) substrings and O(n) to validate each)
    • Space: O(n) for validation checks
      Not efficient for large inputs.

Dynamic Programming Approach

  • Idea:
    Use a DP array where dp[i] represents the length of the longest valid substring ending at index i.

  • Steps:

    1. Initialize a DP array of zeros.
    2. Iterate through the string from index 1 to the end.
    3. If s[i] is ')':
      • If s[i-1] is '(', then update:
        dp[i] = (dp[i-2] if i >= 2 else 0) + 2
      • Else if s[i-1] is ')' and the character before the previous valid substring (at index i-dp[i-1]-1) is '(', update:
        dp[i] = dp[i-1] + 2 + (dp[i-dp[i-1]-2] if (i-dp[i-1]) >= 2 else 0)
    4. Update the maximum length encountered.
  • Complexity:

    • Time: O(n)
    • Space: O(n)

Stack-Based Approach

  • Idea:
    Use a stack to keep track of indices. Push -1 initially to handle edge cases.

  • Steps:

    1. Initialize a stack with -1.
    2. Iterate through the string:
      • If the character is '(', push its index onto the stack.
      • If the character is ')', pop the top of the stack.
        • If the stack is empty after popping, push the current index.
        • Else, update the maximum valid length using:
          current_length = current_index - stack.top()
    3. The maximum value encountered during the iteration is the answer.
  • Complexity:

    • Time: O(n)
    • Space: O(n)

Two-Pass / Counter Approach

  • Idea:
    Use two counters (for left and right parentheses) and scan the string twice—once from left to right and once from right to left.

  • Steps (Left-to-Right):

    1. Initialize left = 0 and right = 0.
    2. For each character:
      • Increment left if the character is '('.
      • Increment right if the character is ')'.
      • If left == right, update the maximum length.
      • If right > left, reset both counters.
  • Steps (Right-to-Left):

    1. Reset left = 0 and right = 0.
    2. Iterate from the end of the string:
      • Increment counters similarly.
      • If left == right, update the maximum length.
      • If left > right, reset both counters.
  • Complexity:

    • Time: O(n)
    • Space: O(1)

Complexity Analysis

  • Brute Force:

    • Time: O(n³)
    • Space: O(n)
  • Dynamic Programming:

    • Time: O(n)
    • Space: O(n)
  • Stack-Based:

    • Time: O(n)
    • Space: O(n)
  • Two-Pass / Counter:

    • Time: O(n)
    • Space: O(1)

Python Code

Python3
Python3

. . . .

Java Code

Java
Java

. . . .

Step-by-Step Walkthrough and Visual Examples

Visual Example (Stack-Based Approach)

For the input ")()())":

  1. Initialization:

    • Stack: [-1] (used to handle edge cases)
  2. Iteration:

    • Index 0:

      • Character: ')'
      • Stack before: [-1]
      • Pop the top (since it's a closing parenthesis) → Stack becomes empty
      • Since the stack is empty, push current index 0
      • Stack now: [0]
    • Index 1:

      • Character: '('
      • Push index 1
      • Stack now: [0, 1]
    • Index 2:

      • Character: ')'
      • Pop index 1
      • Stack now: [0]
      • Valid length: 2 - 0 = 2 → Update max length to 2
    • Index 3:

      • Character: '('
      • Push index 3
      • Stack now: [0, 3]
    • Index 4:

      • Character: ')'
      • Pop index 3
      • Stack now: [0]
      • Valid length: 4 - 0 = 4 → Update max length to 4
    • Index 5:

      • Character: ')'
      • Pop from stack → Stack becomes empty
      • Since the stack is empty, push current index 5
      • Stack now: [5]
  3. Result:

    • Maximum valid length is 4.

Common Mistakes

  • Ignoring Edge Cases:
    Not handling empty strings or strings with only one type of parenthesis.

  • Stack Initialization:
    Forgetting to initialize the stack with -1 in the stack-based approach, which is crucial for calculating lengths correctly.

  • DP Array Updates:
    Incorrectly updating the DP array when a previous valid substring exists, leading to off-by-one errors.

Edge Cases

  • Empty String:
    The string "" should return 0.

  • All Opening or All Closing:
    E.g., "(((" or ")))" should return 0.

  • Entirely Valid String:
    A string like "()()()" should return its full length.

  • Alternating Patterns:
    Strings with alternating patterns that might trick simple counters if not handled correctly.

Alternative Variations

  • Return the Substring:
    Instead of just returning the length, modify the problem to return the longest valid parentheses substring itself.

  • Multiple Types of Brackets:
    Extend the problem to handle multiple types of brackets such as '{', '}', '[', ']' in addition to '(' and ')'.

TAGS
leetcode
CONTRIBUTOR
Design Gurus Team
-

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
Related Courses
Grokking the Coding Interview: Patterns for Coding Questions
Grokking the Coding Interview Patterns in Java, Python, JS, C++, C#, and Go. The most comprehensive course with 476 Lessons.
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
Grokking Data Structures & Algorithms for Coding Interviews
Unlock Coding Interview Success: Dive Deep into Data Structures and Algorithms.
Image
One-Stop Portal For Tech Interviews.
Copyright © 2025 Design Gurus, LLC. All rights reserved.
;