Skip to content

feat: Update solution to lc problem: No.32 #2073

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions solution/0000-0099/0032.Longest Valid Parentheses/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ $$

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

**方法二:使用栈**

- 使用栈来存储左括号的索引,栈底元素初始化为 `-1`,用于辅助计算有效括号的长度。
- 遍历字符串,对于每个字符:
- 如果是左括号,将当前位置压入栈。
- 如果是右括号,弹出栈顶元素表示匹配了一个左括号。
- 如果栈为空,说明当前右括号无法匹配,将当前位置压入栈作为新的起点。
- 如果栈不为空,计算当前有效括号子串的长度,更新最大长度。
- 最终返回最大长度。

总结:这个算法的关键在于维护一个线,栈内存放的是左括号的索引,通过弹出和压入的操作来更新有效括号子串的长度。

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

<!-- tabs:start -->

### **Python3**
Expand All @@ -95,6 +109,23 @@ class Solution:
return max(f)
```

```python
class Solution:
def longestValidParentheses(self, s: str) -> int:
stack = [-1]
ans = 0
for i in range(len(s)):
if s[i] == '(':
stack.append(i)
else:
stack.pop()
if not stack:
stack.append(i)
else:
ans = max(ans, i - stack[-1])
return ans
```

### **Java**

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

```go
func longestValidParentheses(s string) int {
ans := 0
stack := []int{-1}
for i, v := range s {
if v == '(' {
stack = append(stack, i)
} else {
stack = stack[:len(stack)-1]
if len(stack) == 0 {
stack = append(stack, i)
} else {
if ans < i-stack[len(stack)-1] {
ans = i - stack[len(stack)-1]
}
}
}
}
return ans
}
```

### **C#**

```cs
Expand Down Expand Up @@ -216,6 +269,28 @@ function longestValidParentheses(s: string): number {
}
```

```ts
function longestValidParentheses(s: string): number {
let max_length: number = 0;
const stack: number[] = [-1];
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 {
max_length = Math.max(max_length, i - stack[stack.length - 1]);
}
}
}

return max_length;
}
```

### **JavaScript**

```js
Expand All @@ -242,6 +317,90 @@ var longestValidParentheses = function (s) {
};
```

```js
/**
* @param {string} s
* @return {number}
*/
var longestValidParentheses = function (s) {
let ans = 0;
const stack = [-1];
for (i = 0; i < s.length; i++) {
if (s.charAt(i) === '(') {
stack.push(i);
} else {
stack.pop();
if (stack.length === 0) {
stack.push(i);
} else {
ans = Math.max(ans, i - stack[stack.length - 1]);
}
}
}
return ans;
};
```

### Rust

```rust
impl Solution {
pub fn longest_valid_parentheses(s: String) -> i32 {
let mut ans = 0;
let mut f = vec![0; s.len() + 1];
for i in 2..=s.len() {
if
s
.chars()
.nth(i - 1)
.unwrap() == ')'
{
if
s
.chars()
.nth(i - 2)
.unwrap() == '('
{
f[i] = f[i - 2] + 2;
} else if
(i as i32) - f[i - 1] - 1 > 0 &&
s
.chars()
.nth(i - (f[i - 1] as usize) - 2)
.unwrap() == '('
{
f[i] = f[i - 1] + 2 + f[i - (f[i - 1] as usize) - 2];
}
ans = ans.max(f[i]);
}
}
ans
}
}
```

```rust
impl Solution {
pub fn longest_valid_parentheses(s: String) -> i32 {
let mut stack = vec![-1];
let mut res = 0;
for i in 0..s.len() {
if let Some('(') = s.chars().nth(i) {
stack.push(i as i32);
} else {
stack.pop().unwrap();
if stack.is_empty() {
stack.push(i as i32);
} else {
res = std::cmp::max(res, (i as i32) - stack.last().unwrap());
}
}
}
res
}
}
```

### **...**

```
Expand Down
160 changes: 160 additions & 0 deletions solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ Finally, we only need to return $max(f)$.

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

**Solution 2: Using Stack**

- 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.
- Iterate through each element of the string:
- If the character is a left parenthesis, push the index of the character onto the stack.
- If the character is a right parenthesis, pop an element from the stack to represent that we have found a valid pair of parentheses.
- 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.
- If the stack is not empty, calculate the length of the valid parentheses and update it.

Summary:

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.

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

<!-- tabs:start -->

### **Python3**
Expand All @@ -87,6 +102,23 @@ class Solution:
return max(f)
```

```python
class Solution:
def longestValidParentheses(self, s: str) -> int:
stack = [-1]
ans = 0
for i in range(len(s)):
if s[i] == '(':
stack.append(i)
else:
stack.pop()
if not stack:
stack.append(i)
else:
ans = max(ans, i - stack[-1])
return ans
```

### **Java**

```java
Expand Down Expand Up @@ -158,6 +190,28 @@ func longestValidParentheses(s string) int {
}
```

```go
func longestValidParentheses(s string) int {
ans := 0
stack := []int{-1}
for i, v := range s {
if v == '(' {
stack = append(stack, i)
} else {
stack = stack[:len(stack)-1]
if len(stack) == 0 {
stack = append(stack, i)
} else {
if ans < i-stack[len(stack)-1] {
ans = i - stack[len(stack)-1]
}
}
}
}
return ans
}
```

### **C#**

```cs
Expand Down Expand Up @@ -206,6 +260,28 @@ function longestValidParentheses(s: string): number {
}
```

```ts
function longestValidParentheses(s: string): number {
let max_length: number = 0;
const stack: number[] = [-1];
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 {
max_length = Math.max(max_length, i - stack[stack.length - 1]);
}
}
}

return max_length;
}
```

### **JavaScript**

```js
Expand All @@ -232,6 +308,90 @@ var longestValidParentheses = function (s) {
};
```

```js
/**
* @param {string} s
* @return {number}
*/
var longestValidParentheses = function (s) {
let ans = 0;
const stack = [-1];
for (i = 0; i < s.length; i++) {
if (s.charAt(i) === '(') {
stack.push(i);
} else {
stack.pop();
if (stack.length === 0) {
stack.push(i);
} else {
ans = Math.max(ans, i - stack[stack.length - 1]);
}
}
}
return ans;
};
```

### Rust

```rust
impl Solution {
pub fn longest_valid_parentheses(s: String) -> i32 {
let mut ans = 0;
let mut f = vec![0; s.len() + 1];
for i in 2..=s.len() {
if
s
.chars()
.nth(i - 1)
.unwrap() == ')'
{
if
s
.chars()
.nth(i - 2)
.unwrap() == '('
{
f[i] = f[i - 2] + 2;
} else if
(i as i32) - f[i - 1] - 1 > 0 &&
s
.chars()
.nth(i - (f[i - 1] as usize) - 2)
.unwrap() == '('
{
f[i] = f[i - 1] + 2 + f[i - (f[i - 1] as usize) - 2];
}
ans = ans.max(f[i]);
}
}
ans
}
}
```

```rust
impl Solution {
pub fn longest_valid_parentheses(s: String) -> i32 {
let mut stack = vec![-1];
let mut res = 0;
for i in 0..s.len() {
if let Some('(') = s.chars().nth(i) {
stack.push(i as i32);
} else {
stack.pop().unwrap();
if stack.is_empty() {
stack.push(i as i32);
} else {
res = std::cmp::max(res, (i as i32) - stack.last().unwrap());
}
}
}
res
}
}
```

### **...**

```
Expand Down
Loading