刷题笔记:力扣第32题-最长有效括号

1.遇到括号就想用栈,初步想法是只使用top指针来模拟栈,遇到'('就压入栈,遇到')'时,如果栈内有元素(即有剩余'(')就弹出栈,计数值+2;若没有元素,说明不是有效括号,计数值清零。最后记录最大的计数值就是答案。完整代码如下:

cpp 复制代码
 1. int longestValidParentheses(char* s) {
 2.     int top = 0;
 3.     int cnt = 0;
 4.     int res = 0;
 5.  
 6.     for (int i = 0; s[i] != '\0'; i++){
 7.         if (s[i] == '('){
 8.             top++;
 9.         } else {
10.             if (top > 0){
11.                 top--;
12.                 cnt += 2;
13.                 res = fmax(res, cnt);
14.             } else {
15.                 cnt = 0;
16.             }
17.         }
18.     }
19.  
20.     return res;
21. }

可以看到,当前代码无法处理中间有'('作为隔断的情况,它将左右两个括号隔开了,连续最长有效括号应该是2而不是4。

2.正确的做法是设置一个栈,栈内放置括号下标,且栈底元素永远是上一个阻断的括号,称为哨兵括号。栈内首先需要将-1压入栈中充当哨兵下标,这样可以解决边界问题,且如果一开始就有一个完整括号的话(即下标0和1分别为'('和')'时,计算出的长度值恰好为2)。在遇到'('时正常压入栈,遇到')'时出栈,如果此时栈顶指针到底就说明本次遇到的')'没有匹配成功,它成为新的哨兵括号;否则就计算当前长度,此时top指向的是本次匹配上的'('的下标,它应该被弹出了,所以需要再-1指向当前新栈顶,此时的i - stacktop - 1才是长度值。

3.基于以上思想,可写出完整代码如下:

cpp 复制代码
 1. // 最长有效括号
 2. int longestValidParentheses(char* s) {
 3.     int len = strlen(s);
 4.     if (len == 0) return 0;
 5.     int stack[len + 1]; // 栈保存下标,用于计算有效括号区间长度
 6.     int top = 0;
 7.     stack[top++] = -1;  // 哨兵下标,作为有效区间的左边界基准
 8.     int res = 0;        // 记录最长有效括号长度
 9.  
10.     for (int i = 0; i < len; i++){
11.         if (s[i] == '('){
12.             // 左括号:把下标入栈
13.             stack[top++] = i;
14.         } else {
15.             // 右括号:栈顶出栈
16.             top--;
17.             if (top == 0){
18.                 // 栈空,说明当前右括号无法匹配,更新哨兵到当前下标
19.                 stack[top++] = i;
20.             } else {
21.                 // 栈不为空,当前i - 新栈顶即为当前有效括号长度
22.                 res = fmax(res, i - stack[top - 1]);
23.             }
24.         }
25.     }
26.     return res;
27. }

该算法时间复杂度和空间复杂度均为O(n)。

相关推荐
All for pursuit.1 小时前
【动态规划-21】312.戳气球
数据结构·c++·算法·leetcode·动态规划
xian_wwq2 小时前
【学习笔记】Milvus 如何完成一次向量相似度检索,Milvus 索引到底应该怎么选?-15
笔记·学习·milvus
碧海银沙音频科技研究院4 小时前
基于炬芯ATS3089X自研AEC声学回声消除算法
算法
通问AI4 小时前
在两台 Mac Studio 上跑 800B 模型:MLX + RDMA over Thunderbolt 实测与四道门选型法
算法
ZywOo6234 小时前
《算法竞赛进阶指南》0x03 前缀和与差分
算法
Scintilla_y4 小时前
DAY2 滑动窗口
算法·leetcode·散列表
lvwangshu4 小时前
笛卡尔树
算法·图论
026d234 小时前
状态信号只知“其然”不知“其所以然”:变工况机械故障诊断的物理盲区
算法
姜鱼问生5 小时前
备份和服务器在同一台机器上,等于没备份
算法·架构