LeetCode32 最长有效括号
题目
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"
示例 3:
输入:s = ""
输出:0
提示:
0 <= s.length <= 3 * 10⁴
s[i] 为 '(' 或 ')'
方法
动态规划法
栈法
用栈保存字符的下标,栈顶为合法字符的开始下标,
若当前字符为"(",此时可能是合法字符开端,也可能中间的合法值,或者非法字符,但由于需要由后面的右括号确定因此直接入栈
若当前字符为")",此时可能是合法字符的结尾,也可能是中间值,也可能是非法字符
如果栈为空,则说明右括号是结尾分界线或非法值,要比较最大值,
如果栈不为空,则说明是中间值直接抵消前一个
- 时间复杂度:O(n)
- 空间复杂度:O(n)
class Solution {
public int longestValidParentheses(String s) {
int max = 0;
Stack<Integer> stack = new Stack<>();
stack.add(-1);
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
if(c=='('){
stack.push(i);
}else{
stack.pop();
if(stack.isEmpty()){
stack.push(i);
}else{
max = Math.max(max,i-stack.peek());
}
}
}
return max;
}
}
双指针法
左指针记录左括号的个数,右指针记录右括号的个数
若l<r,说明右括号多了,字符不合法了,合法字符的下标要重新计算l=r=0;
若l=r,说明此时字符合法,合法的长度为l*2,此时要比较最大值
若l>r,说明左括号多了,此时无法判断合法的个数
用此方法从0-n遍历能够找到"())"这种右边多的合法个数
同理,从n-0遍历能够得到"(()"这种左边多的合法个数
- 时间复杂度:O(n)
- 空间复杂度:O(1)
class Solution {
public int longestValidParentheses(String s) {
//正序遍历,找出(()))右边多的合法子串
int l = 0,r = 0,max = 0;
int length = s.length();
for(int i=0;i<length;i++){
char c = s.charAt(i);
if(c=='('){
l++;
}else{
r++;
}
if(l==r){
max = Math.max(max,r*2);
}else if(l<r){
l = 0;
r = 0;
}
}
//倒序遍历,找出((())左边多的合法子串
l = r = 0;
for(int i=length-1;i>=0;i--){
char c = s.charAt(i);
if(c=='('){
l++;
}else{
r++;
}
if(l==r){
max = Math.max(max,r*2);
}else if(l>r){
l = 0;
r = 0;
}
}
return max;
}
}
分类:
LeetCode Hot100
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!