52
52
53
53
** 方法一:动态规划**
54
54
55
- 定义 ` dp [i]` 表示以 ` s[i] ` 结尾的最长有效括号的长度,答案为 ` max(dp [i]) ` 。
55
+ 我们定义 $f [ i] $ 表示以 $ s[ i-1 ] $ 结尾的最长有效括号的长度,那么答案就是 $ max(f [ i] )$ 。
56
56
57
- ` dp [i]` 的值有以下几种情况:
57
+ 当 $i \lt 2$ 时,字符串长度小于 $2$,不存在有效括号,因此 $f [ i] = 0$。
58
58
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] $:
62
60
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] $。
64
65
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$ 为字符串的长度。
66
79
67
80
<!-- tabs:start -->
68
81
@@ -76,16 +89,16 @@ class Solution:
76
89
n = len (s)
77
90
if n < 2 :
78
91
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
84
97
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 )
89
102
```
90
103
91
104
### ** Java**
@@ -99,20 +112,19 @@ class Solution {
99
112
if (n < 2 ) {
100
113
return 0 ;
101
114
}
102
- char [] cs = s. toCharArray();
103
- int [] dp = new int [n];
115
+ int [] f = new int [n + 1 ];
104
116
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 ;
109
121
} 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 ];
113
125
}
114
126
}
115
- ans = Math . max(ans, dp [i]);
127
+ ans = Math . max(ans, f [i]);
116
128
}
117
129
}
118
130
return ans;
@@ -127,57 +139,51 @@ class Solution {
127
139
public:
128
140
int longestValidParentheses(string s) {
129
141
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;
137
151
} 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] ;
141
155
}
142
156
}
143
- ans = max(ans, dp[ i] );
144
157
}
145
158
}
146
- return ans ;
159
+ return * max_element(f, f + n + 1) ;
147
160
}
148
161
};
149
162
```
150
163
151
164
### **Go**
152
165
153
166
```go
154
- func longestValidParentheses(s string) int {
167
+ func longestValidParentheses(s string) (ans int) {
155
168
n := len(s)
156
169
if n < 2 {
157
170
return 0
158
171
}
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
168
177
} 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]
175
181
}
176
182
}
177
- ans = max(ans, dp [i])
183
+ ans = max(ans, f [i])
178
184
}
179
185
}
180
- return ans
186
+ return
181
187
}
182
188
183
189
func max(a, b int) int {
@@ -188,6 +194,57 @@ func max(a, b int) int {
188
194
}
189
195
```
190
196
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
+
191
248
### ** ...**
192
249
193
250
```
0 commit comments