题目描述
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-valid-parentheses
思路
思路一:我们可以用栈在遍历给定字符串的过程中去判断到目前为止扫描的子字符串的有效性,同时能得到最长有效字符串的长度。我们首先将 −1 放入栈顶。
对于遇到的每个 ‘(’,我们将它的下标放入栈中。
对于遇到的每个 ‘)’,我们弹出栈顶的元素并将当前元素的下标与弹出元素下标作差,得出当前有效括号字符串的长度。通过这种方法,我们继续计算有效子字符串的长度,并最终返回最长有效子字符串的长度。
这种方法的时间复杂度和空间复杂度均为O(n)
。
思路二:不需要额外的空间。
在这种方法中,我们利用两个计数器 leftCount
和 rightCount
。首先,我们从左到右遍历字符串,对于遇到的每个 ‘(’,我们增加 leftCount
计算器,对于遇到的每个 ‘)’ ,我们增加 rightCount
计数器。每当 leftCount
计数器与 rightCount
计数器相等时,我们计算当前有效字符串的长度,并且记录目前为止找到的最长子字符串。如果 rightCount
计数器比 leftCount
计数器大时,我们将 leftCount
和 rightCount
计数器同时变回 0。
然后再从右到左扫描一遍,获取两次结果中的最大值。
这种方法的时间复杂度和为O(n)
,空间复杂度为O(1)
思路三:采用动态规划的思想:
见https://leetcode-cn.com/problems/longest-valid-parentheses/solution/zui-chang-you-xiao-gua-hao-by-leetcode/
c++
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> stack;
int last = -1;
int maxLen = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] == '('){
stack.push(i);
}else{
if(stack.empty()){
last = i;
} else{
stack.pop();
if(stack.empty()){
maxLen = max(maxLen, i - last);
}else{
maxLen = max(maxLen, i - stack.top());
}
}
}
}
return maxLen;
}
};
class Solution {
public:
int longestValidParentheses(string s) {
int leftCount = 0, rightCount = 0, maxLength = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] == '('){
leftCount ++;
}else{
rightCount ++;
}
if(leftCount == rightCount){
maxLength = max(maxLength, 2 * rightCount);
}else if(leftCount <= rightCount){
leftCount = rightCount = 0;
}
}
leftCount = rightCount = 0;
for(int i = s.size() - 1; i >= 0; i--){
if(s[i] == '('){
leftCount ++;
}else{
rightCount ++;
}
if(leftCount == rightCount){
maxLength = max(maxLength, 2 * leftCount);
}else if(leftCount >= rightCount){
leftCount = rightCount = 0;
}
}
return maxLength;
}
};
class Solution {
public:
int longestValidParentheses(string s) {
int maxLength = 0;
vector<int> dp(s.size());
for (int i = 1; i < s.size(); i++) {
if (s[i] == ')') {
if (s[i-1] == '(') {
dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
} else if (i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == '(') {
dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
}
maxLength = max(maxLength, dp[i]);
}
}
return maxLength;
}
};