diff --git a/solution/0000-0099/0032.Longest Valid Parentheses/README.md b/solution/0000-0099/0032.Longest Valid Parentheses/README.md index 26374b354ad89..ce178465d30da 100644 --- a/solution/0000-0099/0032.Longest Valid Parentheses/README.md +++ b/solution/0000-0099/0032.Longest Valid Parentheses/README.md @@ -73,6 +73,20 @@ $$ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串的长度。 +**方法二:使用栈** + +- 使用栈来存储左括号的索引,栈底元素初始化为 `-1`,用于辅助计算有效括号的长度。 +- 遍历字符串,对于每个字符: + - 如果是左括号,将当前位置压入栈。 + - 如果是右括号,弹出栈顶元素表示匹配了一个左括号。 + - 如果栈为空,说明当前右括号无法匹配,将当前位置压入栈作为新的起点。 + - 如果栈不为空,计算当前有效括号子串的长度,更新最大长度。 +- 最终返回最大长度。 + +总结:这个算法的关键在于维护一个线,栈内存放的是左括号的索引,通过弹出和压入的操作来更新有效括号子串的长度。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串的长度。 + ### **Python3** @@ -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** @@ -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 @@ -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 @@ -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 + } +} +``` + ### **...** ``` diff --git a/solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md b/solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md index 78a9d2b669aa0..e4d4b974df5e9 100644 --- a/solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md +++ b/solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md @@ -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. + ### **Python3** @@ -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 @@ -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 @@ -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 @@ -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 + } +} +``` + ### **...** ``` diff --git a/solution/0000-0099/0032.Longest Valid Parentheses/Solution.rs b/solution/0000-0099/0032.Longest Valid Parentheses/Solution.rs new file mode 100644 index 0000000000000..68aa7b6cd430c --- /dev/null +++ b/solution/0000-0099/0032.Longest Valid Parentheses/Solution.rs @@ -0,0 +1,33 @@ +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 + } +}