Skip to content

Commit 60c30be

Browse files
authored
feat: add solution to lc problem: No.32 (doocs#2073)
1 parent 368c441 commit 60c30be

File tree

3 files changed

+352
-0
lines changed

3 files changed

+352
-0
lines changed

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

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,20 @@ $$
7373

7474
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串的长度。
7575

76+
**方法二:使用栈**
77+
78+
- 使用栈来存储左括号的索引,栈底元素初始化为 `-1`,用于辅助计算有效括号的长度。
79+
- 遍历字符串,对于每个字符:
80+
- 如果是左括号,将当前位置压入栈。
81+
- 如果是右括号,弹出栈顶元素表示匹配了一个左括号。
82+
- 如果栈为空,说明当前右括号无法匹配,将当前位置压入栈作为新的起点。
83+
- 如果栈不为空,计算当前有效括号子串的长度,更新最大长度。
84+
- 最终返回最大长度。
85+
86+
总结:这个算法的关键在于维护一个线,栈内存放的是左括号的索引,通过弹出和压入的操作来更新有效括号子串的长度。
87+
88+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串的长度。
89+
7690
<!-- tabs:start -->
7791

7892
### **Python3**
@@ -95,6 +109,23 @@ class Solution:
95109
return max(f)
96110
```
97111

112+
```python
113+
class Solution:
114+
def longestValidParentheses(self, s: str) -> int:
115+
stack = [-1]
116+
ans = 0
117+
for i in range(len(s)):
118+
if s[i] == '(':
119+
stack.append(i)
120+
else:
121+
stack.pop()
122+
if not stack:
123+
stack.append(i)
124+
else:
125+
ans = max(ans, i - stack[-1])
126+
return ans
127+
```
128+
98129
### **Java**
99130

100131
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -168,6 +199,28 @@ func longestValidParentheses(s string) int {
168199
}
169200
```
170201

202+
```go
203+
func longestValidParentheses(s string) int {
204+
ans := 0
205+
stack := []int{-1}
206+
for i, v := range s {
207+
if v == '(' {
208+
stack = append(stack, i)
209+
} else {
210+
stack = stack[:len(stack)-1]
211+
if len(stack) == 0 {
212+
stack = append(stack, i)
213+
} else {
214+
if ans < i-stack[len(stack)-1] {
215+
ans = i - stack[len(stack)-1]
216+
}
217+
}
218+
}
219+
}
220+
return ans
221+
}
222+
```
223+
171224
### **C#**
172225

173226
```cs
@@ -216,6 +269,28 @@ function longestValidParentheses(s: string): number {
216269
}
217270
```
218271

272+
```ts
273+
function longestValidParentheses(s: string): number {
274+
let max_length: number = 0;
275+
const stack: number[] = [-1];
276+
for (let i = 0; i < s.length; i++) {
277+
if (s.charAt(i) == '(') {
278+
stack.push(i);
279+
} else {
280+
stack.pop();
281+
282+
if (stack.length === 0) {
283+
stack.push(i);
284+
} else {
285+
max_length = Math.max(max_length, i - stack[stack.length - 1]);
286+
}
287+
}
288+
}
289+
290+
return max_length;
291+
}
292+
```
293+
219294
### **JavaScript**
220295

221296
```js
@@ -242,6 +317,90 @@ var longestValidParentheses = function (s) {
242317
};
243318
```
244319

320+
```js
321+
/**
322+
* @param {string} s
323+
* @return {number}
324+
*/
325+
var longestValidParentheses = function (s) {
326+
let ans = 0;
327+
const stack = [-1];
328+
for (i = 0; i < s.length; i++) {
329+
if (s.charAt(i) === '(') {
330+
stack.push(i);
331+
} else {
332+
stack.pop();
333+
if (stack.length === 0) {
334+
stack.push(i);
335+
} else {
336+
ans = Math.max(ans, i - stack[stack.length - 1]);
337+
}
338+
}
339+
}
340+
return ans;
341+
};
342+
```
343+
344+
### Rust
345+
346+
```rust
347+
impl Solution {
348+
pub fn longest_valid_parentheses(s: String) -> i32 {
349+
let mut ans = 0;
350+
let mut f = vec![0; s.len() + 1];
351+
for i in 2..=s.len() {
352+
if
353+
s
354+
.chars()
355+
.nth(i - 1)
356+
.unwrap() == ')'
357+
{
358+
if
359+
s
360+
.chars()
361+
.nth(i - 2)
362+
.unwrap() == '('
363+
{
364+
f[i] = f[i - 2] + 2;
365+
} else if
366+
(i as i32) - f[i - 1] - 1 > 0 &&
367+
s
368+
.chars()
369+
.nth(i - (f[i - 1] as usize) - 2)
370+
.unwrap() == '('
371+
{
372+
f[i] = f[i - 1] + 2 + f[i - (f[i - 1] as usize) - 2];
373+
}
374+
ans = ans.max(f[i]);
375+
}
376+
}
377+
ans
378+
}
379+
}
380+
```
381+
382+
```rust
383+
impl Solution {
384+
pub fn longest_valid_parentheses(s: String) -> i32 {
385+
let mut stack = vec![-1];
386+
let mut res = 0;
387+
for i in 0..s.len() {
388+
if let Some('(') = s.chars().nth(i) {
389+
stack.push(i as i32);
390+
} else {
391+
stack.pop().unwrap();
392+
if stack.is_empty() {
393+
stack.push(i as i32);
394+
} else {
395+
res = std::cmp::max(res, (i as i32) - stack.last().unwrap());
396+
}
397+
}
398+
}
399+
res
400+
}
401+
}
402+
```
403+
245404
### **...**
246405

247406
```

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

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ Finally, we only need to return $max(f)$.
6767

6868
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the string.
6969

70+
**Solution 2: Using Stack**
71+
72+
- Maintain a stack to store the indices of left parentheses. Initialize the bottom element of the stack with the value -1 to facilitate the calculation of the length of valid parentheses.
73+
- Iterate through each element of the string:
74+
- If the character is a left parenthesis, push the index of the character onto the stack.
75+
- If the character is a right parenthesis, pop an element from the stack to represent that we have found a valid pair of parentheses.
76+
- If the stack is empty, it means we couldn't find a left parenthesis to match the right parenthesis. In this case, push the index of the character as a new starting point.
77+
- If the stack is not empty, calculate the length of the valid parentheses and update it.
78+
79+
Summary:
80+
81+
The key to this algorithm is to maintain a stack to store the indices of left parentheses and then update the length of the valid substring of parentheses by pushing and popping elements.
82+
83+
The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the string.
84+
7085
<!-- tabs:start -->
7186

7287
### **Python3**
@@ -87,6 +102,23 @@ class Solution:
87102
return max(f)
88103
```
89104

105+
```python
106+
class Solution:
107+
def longestValidParentheses(self, s: str) -> int:
108+
stack = [-1]
109+
ans = 0
110+
for i in range(len(s)):
111+
if s[i] == '(':
112+
stack.append(i)
113+
else:
114+
stack.pop()
115+
if not stack:
116+
stack.append(i)
117+
else:
118+
ans = max(ans, i - stack[-1])
119+
return ans
120+
```
121+
90122
### **Java**
91123

92124
```java
@@ -158,6 +190,28 @@ func longestValidParentheses(s string) int {
158190
}
159191
```
160192

193+
```go
194+
func longestValidParentheses(s string) int {
195+
ans := 0
196+
stack := []int{-1}
197+
for i, v := range s {
198+
if v == '(' {
199+
stack = append(stack, i)
200+
} else {
201+
stack = stack[:len(stack)-1]
202+
if len(stack) == 0 {
203+
stack = append(stack, i)
204+
} else {
205+
if ans < i-stack[len(stack)-1] {
206+
ans = i - stack[len(stack)-1]
207+
}
208+
}
209+
}
210+
}
211+
return ans
212+
}
213+
```
214+
161215
### **C#**
162216

163217
```cs
@@ -206,6 +260,28 @@ function longestValidParentheses(s: string): number {
206260
}
207261
```
208262

263+
```ts
264+
function longestValidParentheses(s: string): number {
265+
let max_length: number = 0;
266+
const stack: number[] = [-1];
267+
for (let i = 0; i < s.length; i++) {
268+
if (s.charAt(i) == '(') {
269+
stack.push(i);
270+
} else {
271+
stack.pop();
272+
273+
if (stack.length === 0) {
274+
stack.push(i);
275+
} else {
276+
max_length = Math.max(max_length, i - stack[stack.length - 1]);
277+
}
278+
}
279+
}
280+
281+
return max_length;
282+
}
283+
```
284+
209285
### **JavaScript**
210286

211287
```js
@@ -232,6 +308,90 @@ var longestValidParentheses = function (s) {
232308
};
233309
```
234310

311+
```js
312+
/**
313+
* @param {string} s
314+
* @return {number}
315+
*/
316+
var longestValidParentheses = function (s) {
317+
let ans = 0;
318+
const stack = [-1];
319+
for (i = 0; i < s.length; i++) {
320+
if (s.charAt(i) === '(') {
321+
stack.push(i);
322+
} else {
323+
stack.pop();
324+
if (stack.length === 0) {
325+
stack.push(i);
326+
} else {
327+
ans = Math.max(ans, i - stack[stack.length - 1]);
328+
}
329+
}
330+
}
331+
return ans;
332+
};
333+
```
334+
335+
### Rust
336+
337+
```rust
338+
impl Solution {
339+
pub fn longest_valid_parentheses(s: String) -> i32 {
340+
let mut ans = 0;
341+
let mut f = vec![0; s.len() + 1];
342+
for i in 2..=s.len() {
343+
if
344+
s
345+
.chars()
346+
.nth(i - 1)
347+
.unwrap() == ')'
348+
{
349+
if
350+
s
351+
.chars()
352+
.nth(i - 2)
353+
.unwrap() == '('
354+
{
355+
f[i] = f[i - 2] + 2;
356+
} else if
357+
(i as i32) - f[i - 1] - 1 > 0 &&
358+
s
359+
.chars()
360+
.nth(i - (f[i - 1] as usize) - 2)
361+
.unwrap() == '('
362+
{
363+
f[i] = f[i - 1] + 2 + f[i - (f[i - 1] as usize) - 2];
364+
}
365+
ans = ans.max(f[i]);
366+
}
367+
}
368+
ans
369+
}
370+
}
371+
```
372+
373+
```rust
374+
impl Solution {
375+
pub fn longest_valid_parentheses(s: String) -> i32 {
376+
let mut stack = vec![-1];
377+
let mut res = 0;
378+
for i in 0..s.len() {
379+
if let Some('(') = s.chars().nth(i) {
380+
stack.push(i as i32);
381+
} else {
382+
stack.pop().unwrap();
383+
if stack.is_empty() {
384+
stack.push(i as i32);
385+
} else {
386+
res = std::cmp::max(res, (i as i32) - stack.last().unwrap());
387+
}
388+
}
389+
}
390+
res
391+
}
392+
}
393+
```
394+
235395
### **...**
236396

237397
```

0 commit comments

Comments
 (0)