一、Problem
Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"
二、Solution
這題最樸素的做法是枚舉每一段子串,然後用棧檢查每一段子串是否合法,並記錄合法子串的長度,這種方法我試過,會超時…
方法一:棧 + dp
思路
如果當前字符 s[i] 爲右括號 )
,我們很容易想到要找到一個最近的左括號 (
與之匹配,找最近的左括號 (
可以用變量記錄,但我們還要保存之前遇到的左括號 (
,基於這一點我們要可用棧保存左括號的位置,最近的左括號就是棧頂元素
- 定義狀態:
- 表示位置 之前的最長有效括號長度
- 思考初始化:
- 思考狀態轉移方程:
- :表示如果 位置是右括號 、 位置是最接近它的左括號,那麼位置 的長度就可以承接 之前的長度,
- 思考輸出:
class Solution {
public:
int longestValidParentheses(string s) {
int n = s.size(), ans = 0;
stack<int> st;
vector<int> f(n);
for (int i = 0; i < n; i++) {
if (s[i] == '(')
st.push(i);
else if (!st.empty()) {
int j = st.top(), len = i-j+1; st.pop();
if (j > 0) f[i] = f[j-1] + len;
else f[i] = len;
if (f[i] > ans)
ans = f[i];
}
}
return ans;
}
};
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
最近我都在用 C++ 做,真的很方便丫丫,大愛 C++
方法二:空間壓縮
既然 dp 數組的值就是最長有效括號的長度,我們又知道有效括號的最小長度爲 2,所以我們可以用索引 減去 dp 的值來判斷在 位置前是否存在有效括號(i-dp[i-1] > 0
表示存在),這樣可以把棧空間省去…
複雜度分析
- 時間複雜度:,
- 空間複雜度:,