[LeetCode] 32. Longest Valid Parentheses 最长有效括号
Given a string containing just the characters '('
and ')'
, find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is"()"
Example 2:
Input: ")()())
"
Output: 4
Explanation: The longest valid parentheses substring is"()()"
这道求最长有效括号比之前那道 Valid Parentheses 难度要大一些,这里还是借助栈来求解,需要定义个 start 变量来记录合法括号串的起始位置,遍历字符串,如果遇到左括号,则将当前下标压入栈,如果遇到右括号,如果当前栈为空,则将下一个坐标位置记录到 start,如果栈不为空,则将栈顶元素取出,此时若栈为空,则更新结果和 i - start + 1 中的较大值,否则更新结果和 i - st.top() 中的较大值,参见代码如下:
解法一:
class Solution {
public:
int longestValidParentheses(string s) {
int res = , start = , n = s.size();
stack<int> st;
for (int i = ; i < n; ++i) {
if (s[i] == '(') st.push(i);
else if (s[i] == ')') {
if (st.empty()) start = i + ;
else {
st.pop();
res = st.empty() ? max(res, i - start + ) : max(res, i - st.top());
}
}
}
return res;
}
};
还有一种利用动态规划 Dynamic Programming 的解法,可参见网友喜刷刷的博客。这里使用一个一维 dp 数组,其中 dp[i] 表示以 s[i-1] 结尾的最长有效括号长度(注意这里没有对应 s[i],是为了避免取 dp[i-1] 时越界从而让 dp 数组的长度加了1),s[i-1] 此时必须是有效括号的一部分,那么只要 dp[i] 为正数的话,说明 s[i-1] 一定是右括号,因为有效括号必须是闭合的。当括号有重合时,比如 "(())",会出现多个右括号相连,此时更新最外边的右括号的 dp[i] 时是需要前一个右括号的值 dp[i-1],因为假如 dp[i-1] 为正数,说明此位置往前 dp[i-1] 个字符组成的子串都是合法的子串,需要再看前面一个位置,假如是左括号,说明在 dp[i-1] 的基础上又增加了一个合法的括号,所以长度加上2。但此时还可能出现的情况是,前面的左括号前面还有合法括号,比如 "()(())",此时更新最后面的右括号的时候,知道第二个右括号的 dp 值是2,那么最后一个右括号的 dp 值不仅是第二个括号的 dp 值再加2,还可以连到第一个右括号的 dp 值,整个最长的有效括号长度是6。所以在更新当前右括号的 dp 值时,首先要计算出第一个右括号的位置,通过 i-3-dp[i-1] 来获得,由于这里定义的 dp[i] 对应的是字符 s[i-1],所以需要再加1,变成 j = i-2-dp[i-1],这样若当前字符 s[i-1] 是左括号,或者j小于0(说明没有对应的左括号),或者 s[j] 是右括号,此时将 dp[i] 重置为0,否则就用 dp[i-1] + 2 + dp[j] 来更新 dp[i]。这里由于进行了 padding,可能对应关系会比较晕,大家可以自行带个例子一步一步执行,应该是不难理解的,参见代码如下:
解法二:
class Solution {
public:
int longestValidParentheses(string s) {
int res = , n = s.size();
vector<int> dp(n + );
for (int i = ; i <= n; ++i) {
int j = i - - dp[i - ];
if (s[i - ] == '(' || j < || s[j] == ')') {
dp[i] = ;
} else {
dp[i] = dp[i - ] + + dp[j];
res = max(res, dp[i]);
}
}
return res;
}
};
此题还有一种不用额外空间的解法,使用了两个变量 left 和 right,分别用来记录到当前位置时左括号和右括号的出现次数,当遇到左括号时,left 自增1,右括号时 right 自增1。对于最长有效的括号的子串,一定是左括号等于右括号的情况,此时就可以更新结果 res 了,一旦右括号数量超过左括号数量了,说明当前位置不能组成合法括号子串,left 和 right 重置为0。但是对于这种情况 "(()" 时,在遍历结束时左右子括号数都不相等,此时没法更新结果 res,但其实正确答案是2,怎么处理这种情况呢?答案是再反向遍历一遍,采取类似的机制,稍有不同的是此时若 left 大于 right 了,则重置0,这样就可以 cover 所有的情况了,参见代码如下:
解法三:
class Solution {
public:
int longestValidParentheses(string s) {
int res = , left = , right = , n = s.size();
for (int i = ; i < n; ++i) {
(s[i] == '(') ? ++left : ++right;
if (left == right) res = max(res, * right);
else if (right > left) left = right = ;
}
left = right = ;
for (int i = n - ; i >= ; --i) {
(s[i] == '(') ? ++left : ++right;
if (left == right) res = max(res, * left);
else if (left > right) left = right = ;
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/32
类似题目:
Different Ways to Add Parentheses
参考资料:
https://leetcode.com/problems/longest-valid-parentheses/
https://bangbingsyb.blogspot.com/2014/11/leetcode-longest-valid-parentheses.html
https://leetcode.com/problems/longest-valid-parentheses/discuss/14126/My-O(n)-solution-using-a-stack
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 32. Longest Valid Parentheses 最长有效括号的更多相关文章
- [leetcode]32. Longest Valid Parentheses最长合法括号子串
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- 32. Longest Valid Parentheses最长有效括号
参考: 1. https://leetcode.com/problems/longest-valid-parentheses/solution/ 2. https://blog.csdn.net/ac ...
- [LeetCode] Longest Valid Parentheses 最长有效括号
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- leetcode 32. Longest Valid Parentheses
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- Java [leetcode 32]Longest Valid Parentheses
题目描述: Given a string containing just the characters '(' and ')', find the length of the longest vali ...
- LeetCode 32 Longest Valid Parentheses(最长合法的括号组合)
题目链接: https://leetcode.com/problems/longest-valid-parentheses/?tab=Description Problem :已知字符串s,求出其 ...
- 032 Longest Valid Parentheses 最长有效括号
给一个只包含 '(' 和 ')' 的字符串,找出最长的有效(正确关闭)括号子串的长度.对于 "(()",最长有效括号子串为 "()" ,它的长度是 2.另一个例 ...
- [LeetCode] 32. Longest Valid Parentheses (hard)
原题链接 题意: 寻找配对的(),并且返回最长可成功配对长度. 思路 配对的()必须是连续的,比如()((),最长长度为2:()(),最长长度为4. 解法一 dp: 利用dp记录以s[i]为终点时,最 ...
- [Leetcode][Python]32: Longest Valid Parentheses
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 32: Longest Valid Parentheseshttps://oj ...
随机推荐
- redis命令之 ----Hash(哈希表)
HDEL HDEL key field [field ...] 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略. HEXISTS HEXISTS key field 查看哈希表 key ...
- Hashtable 负载因子Load Factor
负载因子(load factor),它用来衡量哈希表的 空/满 程度,一定程度上也可以体现查询的效率,计算公式为: The ratio of the number of elements in the ...
- C# - VS2019WinFrm桌面应用程序FtpClient实现
前言 本篇主要记录:VS2019 WinFrm桌面应用程序实现简单的FtpClient,包含Ftp文件查看.上传和下载等功能. 准备工作 搭建WinFrm前台界面 添加必要的控件,这里主要应用到Gro ...
- python time包中的time.time()和time.clock()的区别
在统计python代码 执行速度时要使用到time包,在查找相关函数时有time.time()和time.clock()两个函数可供选择.而两者是有区别的: cpu 的运行机制:cpu是多任务的,例如 ...
- SAP S4HANA BP事务代码初始界面的ROLE和Grouping配置
SAP S4HANA BP事务代码初始界面的ROLE和Grouping配置 SAP S/4 HANA系统里,创建供应商不再使用MK01/FK01/XK01等事务代码,而是使用BP事务代码. BP事务代 ...
- i春秋-第三届“百越杯”福建省高校网络空间安全大赛-Do you know upload?
进去提示有提示文件包含漏洞 拿到源码发现这里上传验证只有MIME验证 可直接抓包改 image/gif 绕过 接下来就是这次学到的点了 菜刀连接过后怎么都找不到flag文件,但是这里找到了数据库配置文 ...
- ftp上传文件时遇到: ftplib.error_perm: 553 Could not create file
问题描述 今天在使用python的ftplib模块上传文件时,碰到了这样的问题: ftplib.error_perm: 553 Could not create file. 原因 原因是FTP下对应的 ...
- centos7 下面显卡驱动安装
一.安装驱动 屏蔽默认的nouveau cd /lib/modprobe.d/ sudo vim dist-blacklist.conf 将nvidiafb注释掉 #blacklist nvidiaf ...
- Codeforces F. Maxim and Array(构造贪心)
题目描述: Maxim and Array time limit per test 2 seconds memory limit per test 256 megabytes input standa ...
- Scala比较器---Ordered与Ordering
1.Ordered 和 Ordering Scala提供两个特质(trait)Ordered与Ordering用于比较.其中,Ordered混入(mix)Java的Comparable接口,而Orde ...