Skip to main content

32 - Longest Valid Parentheses

Difficulty: Hard | Pattern: Stack / Dynamic Programming | Company tags: Amazon, Google, Microsoft

Problem Statement

Given a string containing just the characters '(' and ')', return the length of the longest valid (well-formed) parentheses substring.

Example 1:

Input: s = "(()"
Output: 2 ("()" is the longest)

Example 2:

Input: s = ")()())"
Output: 4 ("()()" is the longest)

Example 3:

Input: s = ""
Output: 0

Approach 1: Stack — O(n), O(n)

Key insight: Push index of ( onto stack. When ) matches, pop and compute length. Stack bottom is a "fence" — initialize with -1.

def longestValidParentheses(s: str) -> int:
stack = [-1]
max_len = 0

for i, c in enumerate(s):
if c == '(':
stack.append(i)
else:
stack.pop()
if not stack:
stack.append(i) # unmatched ')' becomes new fence
else:
max_len = max(max_len, i - stack[-1])

return max_len

Approach 2: Two Passes (L→R and R→L) — O(n), O(1)

def longestValidParentheses(s: str) -> int:
left = right = max_len = 0

for c in s:
if c == '(':
left += 1
else:
right += 1
if left == right:
max_len = max(max_len, 2 * right)
elif right > left:
left = right = 0

left = right = 0
for c in reversed(s):
if c == '(':
left += 1
else:
right += 1
if left == right:
max_len = max(max_len, 2 * left)
elif left > right:
left = right = 0

return max_len

Dry Run

s = ")()())"

Stack: init=[-1]

icstackmax_len
0)pop -1, empty→push 00
1(push 10
2)pop 1, stack=[-1] → i-(-1)=3-1=22
3(push 32
4)pop 3, stack=[0] → i-0=44
5)pop 0, empty→push 54

Result: 4

Complexity

  • Time: O(n)
  • Space: O(n) stack; O(1) two-pass