LeetCode 32. 最长有效括号
算法1
两遍线性扫描+贪心\(O(n)\)
线性扫描一遍字符串,设置sum = 0,假如是(,就+1,假如是),就-1;计算完之后判断一下当前的和,如果sum == 0说明是有效字符串,统计一下结果。如果是sum < 0说明)太多了,这种情况无论我们输入什么都没法形成有效匹配,如果是sum > 0,说明(太多了,这种情况我们输入),是可以生成有效匹配的。
但是只是这样的话,有一种情况会覆盖不到,那就是扫描到最后,sum > 0,但是字符串里确实有有效串。如...(((()((,最中间的有效匹配会匹配不到。所以我们逆向思维,将整个过程反着来一遍就行了。
时间复杂度
\(O(n)\)
空间复杂度
\(O(1)\)
class Solution {
public:
int longestValidParentheses(string s) {
if (s.empty()) return 0;
int start = 0, sum = 0, res = 0;
for (int i = 0; i < s.size(); i ++)
{
if (s[i] == '(') sum ++;
else if (s[i] == ')') sum --;
if (sum < 0) start = i + 1, sum = 0;
else if (sum == 0) res = max(res, i - start + 1);
}
start = s.size()-1, sum = 0;
for (int i = s.size()-1; i >= 0; i --)
{
if (s[i] == ')') sum ++;
else if (s[i] == '(') sum --;
if (sum < 0) start = i - 1, sum = 0;
else if (sum == 0) res = max(res, start - i + 1);
}
return res;
}
};
算法2
(动态规划)\(O(n)\)

时间复杂度
\(O(n)\)
空间复杂度
\(O(n)\)
class Solution {
public:
int longestValidParentheses(string s) {
int n = s.size();
if (!n) return 0;
vector<int> f(n, 0);
for (int i = 1; i < n; i ++)
{
if (s[i] == ')')
{
if (s[i-1] == '(')
{
if (i >= 2) f[i] = f[i-2] + 2;
else f[i] = 2;
}
else
{
if (i-1-f[i-1] >= 0 && s[i-1-f[i-1]] == '(')
if (i - f[i-1] - 2 >= 0) f[i] = f[i-1] + 2 + f[i - f[i-1] - 2];
else f[i] = f[i-1] + 2;
}
}
}
int res = 0;
for (int i = 0; i < n; i ++) res = max(res, f[i]);
return res;
}
};
Tip
写动规一定要注意转移方程、条件各个地方的下标!
算法3
栈 \(O(n)\)
用栈来维护字符串中待匹配的(,用start来记录当前可能形成最长合法字串的起始位置。
- 当当前输入的字符串为
(时,直接入栈 - 当输入
),但是栈为空,说明不会再有输入能合法化目前的字符串,更新start = i + 1。 - 当输入
),但是栈不为空,栈顶元素出栈,若之后栈为空,说明找到了一个完全合法的子串,更新一下答案res=max(res, i - start + 1);若之后栈不为空,说明找到了一个部分合法的子串,更新一下答案为res = max(res, i - st.top())。
时间复杂度
每个元素最多只会入栈出栈一次,因此是\(O(n)\)
空间复杂度
\(O(n)\)
class Solution {
public:
int longestValidParentheses(string s) {
int n = s.size();
if (!n) return 0;
stack<int> st;
int start = 0, res = 0;
for (int i = 0; i < n; i ++)
{
if (s[i] == '(') st.push(i);
else
{
if (st.empty()) start = i + 1;
else
{
st.pop();
if (st.empty()) res = max(res, i - start + 1);
// 忘了
else res = max(res, i - st.top());
}
}
}
return res;
}
};
Tip
更进一步想,算法1是不是算法2更进一步思考的结果?算法2中栈的元素,假如我们也按算法1给它计算一下,是不是也是满足相应的关系?

浙公网安备 33010602011771号