題目描述
難度:困難
給定一個只包含 '(' 和 ')' 的字符串,找出最長的包含有效括號的子串的長度。
示例 1:
輸入: "(()"
輸出: 2
解釋: 最長有效括號子串爲 "()"
示例 2:
輸入: ")()())"
輸出: 4
解釋: 最長有效括號子串爲 "()()"
思路一——棧
最開始未考慮嵌套括號 “(())” 這種情況,還想着怎麼是困難題。後來 “()(()” 被這種中間斷開也給制裁了。
查看官方題解,初始化一個用於存放字符下標的棧,並置入-1作初值。
遍歷字符串,若字符是 '(' 時,直接入棧;若字符是 ')' ,先將棧中元素移出,然後判空,若棧空,放入當前索引記錄,防止對空棧操作;若棧不爲空,通過當前索引 - 棧頂元素的索引,能夠得到當前有效括號區間的長度。
- 時間複雜度:O(n)
- 空間複雜度:O(n)
int longestValidParentheses(string s) {
int maxLength = 0, length = 0;
stack<int> index;
index.push(-1);
for (int i = 0; i < s.length(); i++)
{
if (s[i] == '(')
index.push(i);
else
{
index.pop();
if(index.empty())
index.push(i);
else
maxLength = max(maxLength,i-index.top());
}
}
return maxLength;
}
思路二——暴力
有效的括號區間一定是偶數個,因此遍歷字符串,挨個字符當作起始點,2個、4個、6個……逐區間使用棧來判斷是否符合規則。這種暴力想法,我也沒想到,不過時間複雜度 O(n^3) 過高,會超時。
例子:
"((())"從索引0開始
2個:(( --> 無效
4個:((()--> 無效
從索引1開始
2個:(( --> 無效4個:(())--> 有效
從索引2開始
2個:() --> 有效從索引3開始
)) --> 無效綜上
最長長度爲 4
class Solution {
public:
bool isValid(string str)
{
stack<char> myStack;
for(int i=0;i<str.length();i++)
{
if(str[i]=='(')
myStack.push(str[i]);
else if(!myStack.empty() && myStack.top() == '(')
myStack.pop();
else
return false;
}
return myStack.empty();
}
int longestValidParentheses(string s) {
int maxLength=0;
for(int i=0;i<s.length();i++)
for (int j = 2; i + j <= s.length(); j += 2)
if (isValid(s.substr(i, j)))
maxLength = max(maxLength, j);
return maxLength;
}
};