Skip to content

Commit 2501424

Browse files
committed
feat: add solutions to lc problem: No.0032
No.0032.Longest Valid Parentheses
1 parent daa0112 commit 2501424

File tree

9 files changed

+284
-188
lines changed

9 files changed

+284
-188
lines changed

solution/0000-0099/0032.Longest Valid Parentheses/README.md

+113-56
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,30 @@
5252

5353
**方法一:动态规划**
5454

55-
定义 `dp[i]` 表示以 `s[i]` 结尾的最长有效括号的长度,答案为 `max(dp[i])`
55+
我们定义 $f[i]$ 表示以 $s[i-1]$ 结尾的最长有效括号的长度,那么答案就是 $max(f[i])$
5656

57-
`dp[i]` 的值有以下几种情况:
57+
当 $i \lt 2$ 时,字符串长度小于 $2$,不存在有效括号,因此 $f[i] = 0$。
5858

59-
-`s[i]``(`,那么 `dp[i] = 0`
60-
-`s[i]``)`,且 `s[i - 1]``(`,那么 `dp[i] = dp[i - 2] + 2`
61-
-`s[i]``)`,且 `s[i - 1]``)``s[i - dp[i - 1] - 1]``(`,那么 `dp[i] = dp[i - 1] + 2 + dp[i - dp[i - 1] - 2]`
59+
当 $i \ge 2$ 时,我们考虑以 $s[i-1]$ 结尾的最长有效括号的长度 $f[i]$:
6260

63-
以上需要注意边界的判断处理。
61+
- 如果 $s[i-1]$ 是左括号,那么以 $s[i-1]$ 结尾的最长有效括号的长度一定为 $0$,因此 $f[i] = 0$。
62+
- 如果 $s[i-1]$ 是右括号,有以下两种情况:
63+
- 如果 $s[i-2]$ 是左括号,那么以 $s[i-1]$ 结尾的最长有效括号的长度为 $f[i-2] + 2$。
64+
- 如果 $s[i-2]$ 是右括号,那么以 $s[i-1]$ 结尾的最长有效括号的长度为 $f[i-1] + 2$,但是还需要考虑 $s[i-f[i-1]-2]$ 是否是左括号,如果是左括号,那么以 $s[i-1]$ 结尾的最长有效括号的长度为 $f[i-1] + 2 + f[i-f[i-1]-2]$。
6465

65-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 `s` 的长度。
66+
因此,我们可以得到状态转移方程:
67+
68+
$$
69+
\begin{cases}
70+
f[i] = 0, & \text{if } s[i-1] = '(',\\
71+
f[i] = f[i-2] + 2, & \text{if } s[i-1] = ')' \text{ and } s[i-2] = '(',\\
72+
f[i] = f[i-1] + 2 + f[i-f[i-1]-2], & \text{if } s[i-1] = ')' \text{ and } s[i-2] = ')' \text{ and } s[i-f[i-1]-2] = '(',\\
73+
\end{cases}
74+
$$
75+
76+
最后,我们只需要返回 $max(f)$ 即可。
77+
78+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串的长度。
6679

6780
<!-- tabs:start -->
6881

@@ -76,16 +89,16 @@ class Solution:
7689
n = len(s)
7790
if n < 2:
7891
return 0
79-
dp = [0] * n
80-
for i in range(1, n):
81-
if s[i] == ')':
82-
if s[i - 1] == '(':
83-
dp[i] = 2 + (dp[i - 2] if i > 1 else 0)
92+
f = [0] * (n + 1)
93+
for i in range(2, n + 1):
94+
if s[i - 1] == ')':
95+
if s[i - 2] == '(':
96+
f[i] = f[i - 2] + 2
8497
else:
85-
j = i - dp[i - 1] - 1
86-
if j >= 0 and s[j] == '(':
87-
dp[i] = 2 + dp[i - 1] + (dp[j - 1] if j else 0)
88-
return max(dp)
98+
j = i - f[i - 1] - 1
99+
if j > 0 and s[j - 1] == '(':
100+
f[i] = f[i - 1] + 2 + f[j - 1]
101+
return max(f)
89102
```
90103

91104
### **Java**
@@ -99,20 +112,19 @@ class Solution {
99112
if (n < 2) {
100113
return 0;
101114
}
102-
char[] cs = s.toCharArray();
103-
int[] dp = new int[n];
115+
int[] f = new int[n + 1];
104116
int ans = 0;
105-
for (int i = 1; i < n; ++i) {
106-
if (cs[i] == ')') {
107-
if (cs[i - 1] == '(') {
108-
dp[i] = 2 + (i > 1 ? dp[i - 2] : 0);
117+
for (int i = 2; i <= n; ++i) {
118+
if (s.charAt(i - 1) == ')') {
119+
if (s.charAt(i - 2) == '(') {
120+
f[i] = f[i - 2] + 2;
109121
} else {
110-
int j = i - dp[i - 1] - 1;
111-
if (j >= 0 && cs[j] == '(') {
112-
dp[i] = 2 + dp[i - 1] + (j > 0 ? dp[j - 1] : 0);
122+
int j = i - f[i - 1] - 1;
123+
if (j > 0 && s.charAt(j - 1) == '(') {
124+
f[i] = f[i - 1] + 2 + f[j - 1];
113125
}
114126
}
115-
ans = Math.max(ans, dp[i]);
127+
ans = Math.max(ans, f[i]);
116128
}
117129
}
118130
return ans;
@@ -127,57 +139,51 @@ class Solution {
127139
public:
128140
int longestValidParentheses(string s) {
129141
int n = s.size();
130-
if (n < 2) return 0;
131-
vector<int> dp(n);
132-
int ans = 0;
133-
for (int i = 1; i < n; ++i) {
134-
if (s[i] == ')') {
135-
if (s[i - 1] == '(') {
136-
dp[i] = 2 + (i > 1 ? dp[i - 2] : 0);
142+
if (n < 2) {
143+
return 0;
144+
}
145+
int f[n + 1];
146+
memset(f, 0, sizeof(f));
147+
for (int i = 2; i <= n; ++i) {
148+
if (s[i - 1] == ')') {
149+
if (s[i - 2] == '(') {
150+
f[i] = f[i - 2] + 2;
137151
} else {
138-
int j = i - dp[i - 1] - 1;
139-
if (~j && s[j] == '(') {
140-
dp[i] = 2 + dp[i - 1] + (j ? dp[j - 1] : 0);
152+
int j = i - f[i - 1] - 1;
153+
if (j && s[j - 1] == '(') {
154+
f[i] = f[i - 1] + 2 + f[j - 1];
141155
}
142156
}
143-
ans = max(ans, dp[i]);
144157
}
145158
}
146-
return ans;
159+
return *max_element(f, f + n + 1);
147160
}
148161
};
149162
```
150163
151164
### **Go**
152165
153166
```go
154-
func longestValidParentheses(s string) int {
167+
func longestValidParentheses(s string) (ans int) {
155168
n := len(s)
156169
if n < 2 {
157170
return 0
158171
}
159-
dp := make([]int, n)
160-
ans := 0
161-
for i := 1; i < n; i++ {
162-
if s[i] == ')' {
163-
if s[i-1] == '(' {
164-
dp[i] = 2
165-
if i > 1 {
166-
dp[i] += dp[i-2]
167-
}
172+
f := make([]int, n+1)
173+
for i := 2; i <= n; i++ {
174+
if s[i-1] == ')' {
175+
if s[i-2] == '(' {
176+
f[i] = f[i-2] + 2
168177
} else {
169-
j := i - dp[i-1] - 1
170-
if j >= 0 && s[j] == '(' {
171-
dp[i] = 2 + dp[i-1]
172-
if j > 0 {
173-
dp[i] += dp[j-1]
174-
}
178+
j := i - f[i-1] - 1
179+
if j > 0 && s[j-1] == '(' {
180+
f[i] = f[i-1] + 2 + f[j-1]
175181
}
176182
}
177-
ans = max(ans, dp[i])
183+
ans = max(ans, f[i])
178184
}
179185
}
180-
return ans
186+
return
181187
}
182188
183189
func max(a, b int) int {
@@ -188,6 +194,57 @@ func max(a, b int) int {
188194
}
189195
```
190196

197+
### **C#**
198+
199+
```cs
200+
public class Solution {
201+
public int LongestValidParentheses(string s) {
202+
int n = s.Length;
203+
if (n < 2) {
204+
return 0;
205+
}
206+
int[] f = new int[n + 1];
207+
int ans = 0;
208+
for (int i = 2; i <= n; ++i) {
209+
if (s[i - 1] == ')') {
210+
if (s[i - 2] == '(') {
211+
f[i] = f[i - 2] + 2;
212+
} else {
213+
int j = i - f[i - 1] - 1;
214+
if (j > 0 && s[j - 1] == '(') {
215+
f[i] = f[i - 1] + 2 + f[j - 1];
216+
}
217+
}
218+
ans = Math.Max(ans, f[i]);
219+
}
220+
}
221+
return ans;
222+
}
223+
}
224+
```
225+
226+
### **TypeScript**
227+
228+
```ts
229+
function longestValidParentheses(s: string): number {
230+
const n = s.length;
231+
const f: number[] = new Array(n + 1).fill(0);
232+
for (let i = 2; i <= n; ++i) {
233+
if (s[i - 1] == ')') {
234+
if (s[i - 2] == '(') {
235+
f[i] = f[i - 2] + 2;
236+
} else {
237+
const j = i - f[i - 1] - 1;
238+
if (j && s[j - 1] == '(') {
239+
f[i] = f[i - 1] + 2 + f[j - 1];
240+
}
241+
}
242+
}
243+
}
244+
return Math.max(...f);
245+
}
246+
```
247+
191248
### **...**
192249

193250
```

0 commit comments

Comments
 (0)