Longest Valid Parentheses — Solution in Python, Java & C++
Longest Valid Parentheses solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A hard problem.
Longest Valid Parentheses is a hard coding problem on strings, dynamic programming and stack, asked in Amazon, Google, Microsoft and Meta interviews.
- Difficulty: Hard
- Topics: Strings, Dynamic Programming, Stack
- Asked at: Amazon, Google, Microsoft, Meta, Morgan Stanley
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Given a string s of '(' and ')', return the length of the longest valid (well-formed and contiguous) parentheses substring.
Example 1
Input: s = "(()"
Output: 2
Explanation: The longest valid substring is "()".
Example 2
Input: s = ")()())"
Output: 4
Example 3
Input: s = ""
Output: 0
Constraints
0 <= s.length <= 40s consists of '(' and ')'.
Hints for Longest Valid Parentheses
Hint 1
Keep a stack of indices, seeded with
-1to mark the base of the current valid run.Hint 2
Push the index of every
(; on a), pop.Hint 3
If the stack empties, this
)is unmatched — push its index as the new base; otherwise the run length is the current index minus the new top.
How to solve Longest Valid Parentheses
Keep a stack of indices seeded with -1 as the base of the current valid run; push ( indices, pop on ), and either record i - newTop or, if the stack empties, push i as the new base.
Approach
- Start
stack = [-1]. - On
(, pushi; on), pop; if empty, pushi; elsebest = max(best, i - stack[-1]). - Return
best.
Why it works
The top of the stack after a successful pop is the index just before the current valid run began, so i - top is its length. An unmatched ) resets the base because nothing valid can span it.
Complexity
- Time —
O(n) - Space —
O(n)
Pitfalls
- The two-counter O(1) approach scans both directions to handle
(()and())symmetrically.
Reference solution
Python
def longestValidParentheses(s: str) -> int:
stack = [-1]
best = 0
for i, ch in enumerate(s):
if ch == "(":
stack.append(i)
else:
stack.pop()
if not stack:
stack.append(i)
else:
best = max(best, i - stack[-1])
return bestJava
public static int longestValidParentheses(String s) {
Deque<Integer> stack = new ArrayDeque<>();
stack.push(-1);
int best = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
} else {
stack.pop();
if (stack.isEmpty()) {
stack.push(i);
} else {
best = Math.max(best, i - stack.peek());
}
}
}
return best;
}C++
int longestValidParentheses(string s) {
vector<int> stack;
stack.push_back(-1);
int best = 0;
for (int i = 0; i < (int) s.size(); i++) {
if (s[i] == '(') {
stack.push_back(i);
} else {
stack.pop_back();
if (stack.empty()) {
stack.push_back(i);
} else {
best = max(best, i - stack.back());
}
}
}
return best;
}JavaScript
var longestValidParentheses = function(s) {
const stack = [-1];
let best = 0;
for (let i = 0; i < s.length; i++) {
if (s.charAt(i) === "(") {
stack.push(i);
} else {
stack.pop();
if (stack.length === 0) {
stack.push(i);
} else {
const len = i - stack[stack.length - 1];
if (len > best) best = len;
}
}
}
return best;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 515 strings problems · the whole catalogue
Learn the technique: Strings · Dynamic Programming