We can use a stack to keep track of the indices of opening parentheses. When we encounter a closing parenthesis, we check if there is a matching opening parenthesis on the stack. If so, we pop it and calculate the length of the valid substring. If not, we update the starting point for the next possible valid substring. This approach helps us efficiently find the longest well-formed parentheses substring.
funlongestValidParentheses(s: String): Int {
val stack = ArrayDeque<Int>()
var maxLen = 0var start = -1// Start of the current valid substring
for (i in s.indices) {
val c = s[i]
if (c =='(') {
stack.addLast(i)
} else {
if (stack.isEmpty()) {
start = i // Unmatched ')', update start
} else {
stack.removeLast() // Found a matching '('
if (stack.isEmpty()) {
maxLen = maxOf(maxLen, i - start)
} else {
maxLen = maxOf(maxLen, i - stack.last())
}
}
}
}
return maxLen
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
deflongestValidParentheses(s: str) -> int:
stack = []
max_len =0 start =-1# Start of the current valid substringfor i, c in enumerate(s):
if c =='(': # Push index of '(' stack.append(i)
else:
ifnot stack:
start = i # Unmatched ')', update startelse:
stack.pop() # Found a matching '('ifnot stack:
max_len = max(max_len, i - start)
else:
max_len = max(max_len, i - stack[-1])
return max_len
We can solve this problem without using a stack by counting the number of opening and closing parentheses as we scan the string. By making two passes—one from left to right and another from right to left—we can handle both cases where there are extra closing or opening parentheses. This approach allows us to find the longest valid substring using only a few variables.
intlongestValidParentheses(const std::string& s) {
int maxLen =0, open =0, close =0, n = s.size();
// Left to right
for (int i =0; i < n; ++i) {
if (s[i] =='(') open++;
else close++;
if (open == close) maxLen = std::max(maxLen, 2* close);
elseif (close > open) open = close =0;
}
open = close =0;
// Right to left
for (int i = n -1; i >=0; --i) {
if (s[i] =='(') open++;
else close++;
if (open == close) maxLen = std::max(maxLen, 2* open);
elseif (open > close) open = close =0;
}
return maxLen;
}
funclongestValidParentheses(sstring) int {
maxLen, open, close:=0, 0, 0n:= len(s)
// Left to rightfori:=0; i < n; i++ {
ifs[i] =='(' {
open++ } else {
close++ }
ifopen==close {
if2*close > maxLen {
maxLen = 2*close }
} elseifclose > open {
open, close = 0, 0 }
}
open, close = 0, 0// Right to leftfori:=n-1; i>=0; i-- {
ifs[i] =='(' {
open++ } else {
close++ }
ifopen==close {
if2*open > maxLen {
maxLen = 2*open }
} elseifopen > close {
open, close = 0, 0 }
}
returnmaxLen}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
publicintlongestValidParentheses(String s) {
int maxLen = 0, open = 0, close = 0, n = s.length();
// Left to rightfor (int i = 0; i < n; i++) {
if (s.charAt(i) =='(') open++;
else close++;
if (open == close) maxLen = Math.max(maxLen, 2 * close);
elseif (close > open) open = close = 0;
}
open = close = 0;
// Right to leftfor (int i = n - 1; i >= 0; i--) {
if (s.charAt(i) =='(') open++;
else close++;
if (open == close) maxLen = Math.max(maxLen, 2 * open);
elseif (open > close) open = close = 0;
}
return maxLen;
}
funlongestValidParentheses(s: String): Int {
var maxLen = 0var open = 0var close = 0val n = s.length
// Left to right
for (i in0 until n) {
if (s[i] =='(') open++else close++if (open== close) maxLen = maxOf(maxLen, 2 * close)
elseif (close > open) { open = 0; close = 0 }
}
open = 0; close = 0// Right to left
for (i in n - 1 downTo 0) {
if (s[i] =='(') open++else close++if (open== close) maxLen = maxOf(maxLen, 2 * open)
elseif (open > close) { open = 0; close = 0 }
}
return maxLen
}
deflongestValidParentheses(s: str) -> int:
max_len = open = close =0 n = len(s)
# Left to rightfor i in range(n):
if s[i] =='(': open +=1else: close +=1if open == close:
max_len = max(max_len, 2* close)
elif close > open:
open = close =0 open = close =0# Right to leftfor i in range(n -1, -1, -1):
if s[i] =='(': open +=1else: close +=1if open == close:
max_len = max(max_len, 2* open)
elif open > close:
open = close =0return max_len
pubfnlongest_valid_parentheses(s: &str) -> i32 {
let n = s.len();
let bytes = s.as_bytes();
letmut max_len =0;
let (mut open, mut close) = (0, 0);
// Left to right
for i in0..n {
if bytes[i] ==b'(' { open +=1; } else { close +=1; }
if open == close {
max_len = max_len.max(2* close);
} elseif close > open {
open =0; close =0;
}
}
open =0; close =0;
// Right to left
for i in (0..n).rev() {
if bytes[i] ==b'(' { open +=1; } else { close +=1; }
if open == close {
max_len = max_len.max(2* open);
} elseif open > close {
open =0; close =0;
}
}
max_len asi32}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
functionlongestValidParentheses(s: string):number {
letmaxLen=0, open=0, close=0, n=s.length;
// Left to right
for (leti=0; i<n; i++) {
if (s[i] ==='(') open++;
elseclose++;
if (open===close) maxLen= Math.max(maxLen, 2*close);
elseif (close>open) open=close=0;
}
open=close=0;
// Right to left
for (leti=n-1; i>=0; i--) {
if (s[i] ==='(') open++;
elseclose++;
if (open===close) maxLen= Math.max(maxLen, 2*open);
elseif (open>close) open=close=0;
}
returnmaxLen;
}
We can use dynamic programming to keep track of the length of the longest valid parentheses substring ending at each position. By building up a DP array, we can efficiently compute the answer by considering previous results and extending them when we find matching pairs.
publicintlongestValidParentheses(String s) {
int[] dp =newint[s.length()];
int result = 0;
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) ==')') {
if (s.charAt(i-1) =='(') {
dp[i]= (i >= 2 ? dp[i-2] : 0) + 2;
} elseif (i - dp[i-1]- 1 >= 0 && s.charAt(i - dp[i-1]- 1) =='(') {
dp[i]= dp[i-1]+ 2 + (i - dp[i-1]- 2 >= 0 ? dp[i - dp[i-1]- 2] : 0);
}
result = Math.max(result, dp[i]);
}
}
return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
funlongestValidParentheses(s: String): Int {
val n = s.length
val dp = IntArray(n)
var result = 0for (i in1 until n) {
if (s[i] ==')') {
if (s[i-1] =='(') {
dp[i] = (if (i >=2) dp[i-2] else0) + 2 } elseif (i - dp[i-1] - 1>=0&& s[i - dp[i-1] - 1] =='(') {
dp[i] = dp[i-1] + 2 + if (i - dp[i-1] - 2>=0) dp[i - dp[i-1] - 2] else0 }
result = maxOf(result, dp[i])
}
}
return result
}
1
2
3
4
5
6
7
8
9
10
11
12
deflongestValidParentheses(s: str) -> int:
n = len(s)
dp = [0] * n
result =0for i in range(1, n):
if s[i] ==')':
if s[i-1] =='(':
dp[i] = (dp[i-2] if i >=2else0) +2elif i - dp[i-1] -1>=0and s[i - dp[i-1] -1] =='(':
dp[i] = dp[i-1] +2+ (dp[i - dp[i-1] -2] if i - dp[i-1] -2>=0else0)
result = max(result, dp[i])
return result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
pubfnlongest_valid_parentheses(s: &str) -> i32 {
let n = s.len();
let bytes = s.as_bytes();
letmut dp =vec![0; n];
letmut result =0;
for i in1..n {
if bytes[i] ==b')' {
if bytes[i-1] ==b'(' {
dp[i] =if i >=2 { dp[i-2] } else { 0 } +2;
} elseif i asi32- dp[i-1] asi32-1>=0&& bytes[i - dp[i-1] -1] ==b'(' {
dp[i] = dp[i-1] +2+if i - dp[i-1] -2< n { dp[i - dp[i-1] -2] } else { 0 };
}
result = result.max(dp[i]);
}
}
result asi32}