1. 题目来源
链接:32. 最长有效括号
2. 题目解析
力扣,前 32 题中最考验思维的一道题,思维题就难的离谱…
简单总结思路:
- 首先进行答案所在组的划分。当一个区间的右括号数量大于左括号数量后,以该右括号为分界点,作为一个组。可严格证明得到,有效答案都在一个组中,不会横跨两个组。
- 采用栈来求出组内的每个右括号所对应的最长匹配的左括号。注意中间已经完成匹配的括号,若一开始栈就是空的,那么说明该右括号就是分界点,更新这个分界点。若栈非空,则说明栈中有左括号,则两者匹配,应该将这个栈顶左括号先弹栈,查看它的左边的那个当前不能匹配的括号。即原栈顶下面的那个左括号。若弹栈后,栈不为空,则用右括号下标减去新栈顶左括号下标即可得到该右括号的最大匹配长度。若栈为空,则说明从区间起点至该右括号全部匹配完成,则用该右括号减去上一个分界点位置即可。
- 分界点一定是新区间起点的前一个点,这样减起来才是从起点到右括号的匹配距离。
- 右括号匹配的最左左括号一定是栈顶的下一个左括号位置,跟它相减。因为中间包含着可能已经匹配完成的部分括号,且那个左括号代表着自它以后,到该右括号均匹配完成,从定义出发,就是该右括号的最大匹配距离。
这题感觉没有拓展性,且很难,但很有趣啊~
看了看题解,貌似可以 dp
,貌似还可以
O
(
1
)
O(1)
O(1) 空间。。。日后再补?
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码:
class Solution {
public:
int longestValidParentheses(string s) {
stack<int> stk;
int res = 0, start = -1;
for (int i = 0; i < s.size(); i ++ ) {
if (s[i] == '(') stk.push(i);
else {
if (stk.size()) {
stk.pop();
if (stk.size()) res = max(res, i - stk.top());
else res = max(res, i - start);
}
else start = i;
}
}
return res;
}
};