[LeetCode] 32. 最長有效括號
阿新 • • 發佈:2019-05-04
leet lan 輸出 null ges tac etc pub pytho ,我們用棧可以找到,
題目鏈接 : https://leetcode-cn.com/problems/longest-valid-parentheses/
題目描述:
給定一個只包含 ‘(‘
和 ‘)‘
的字符串,找出最長的包含有效括號的子串的長度。
示例:
示例 1:
輸入: "(()"
輸出: 2
解釋: 最長有效括號子串為 "()"
示例 2:
輸入: ")()())"
輸出: 4
解釋: 最長有效括號子串為 "()()"
思路:
常規思路1:
對於這種括號匹配問題,一般都是使用棧
我們先找到所有可以匹配的索引號,然後找出最長連續數列!
例如:s = )(()())
位置2
和位置3
匹配,
位置4
和位置5
匹配,
位置1
和位置6
匹配,
這個數組為:2,3,4,5,1,6
這是通過棧找到的,我們按遞增排序!1,2,3,4,5,6
找出該數組的最長連續數列的長度就是最長有效括號長度!
所以時間復雜度來自排序:O(nlogn)
接下來我們思考,是否可以在省略排序的過程,在彈棧時候進行操作!
直接看代碼理解!所以時間復雜度為:O(n)
思路2:
dp方法:
我們用dp[i]
表示以i
結尾的最長有效括號;
當
s[i]
為(
,dp[i]
必然等於0
,因為不可能組成有效的括號;那麽
s[i]
為)
2.1 當
s[i-1]
為(
,那麽dp[i] = dp[i-2] + 2
2.2 當
s[i-1]
為)
並且s[i-dp[i-1] - 1]
為(
,那麽dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2]
;
時間復雜度:\(O(n)\)
關註我的知乎專欄,了解更多解題技巧,大家共同進步!
代碼:
思路一:
class Solution: def longestValidParentheses(self, s: str) -> int: if not s: return 0 res = [] stack = [] for i in range(len(s)): if stack and s[i] == ")": res.append(stack.pop()) res.append(i) if s[i] == "(": stack.append(i) res.sort() #print(res) i = 0 ans = 0 n = len(res) while i < n: j = i while j < n - 1 and res[j + 1] == res[j] + 1: j += 1 ans = max(ans, j - i + 1) i = j + 1 return ans
優化:
python
class Solution:
def longestValidParentheses(self, s: str) -> int:
if not s:
return 0
res = 0
stack = [-1]
for i in range(len(s)):
if s[i] == "(":
stack.append(i)
else:
stack.pop()
if not stack:
stack.append(i)
else:
res = max(res,i - stack[-1])
return res
java
class Solution {
public int longestValidParentheses(String s) {
if (s == null || s.length() == 0) return 0;
Deque<Integer> stack = new ArrayDeque<>();
stack.push(-1);
//System.out.println(stack);
int res = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') stack.push(i);
else {
stack.pop();
if (stack.isEmpty()) stack.push(i);
else {
res = Math.max(res, i - stack.peek());
}
}
}
return res;
}
}
思路2:dp
python
class Solution:
def longestValidParentheses(self, s: str) -> int:
n = len(s)
if n == 0: return 0
dp = [0] * n
res = 0
for i in range(n):
if i>0 and s[i] == ")":
if s[i - 1] == "(":
dp[i] = dp[i - 2] + 2
elif s[i - 1] == ")" and i - dp[i - 1] - 1 >= 0 and s[i - dp[i - 1] - 1] == "(":
dp[i] = dp[i - 1] + 2 + dp[i - dp[i - 1] - 2]
if dp[i] > res:
res = dp[i]
return res
java
class Solution {
public int longestValidParentheses(String s) {
if (s == null || s.length() == 0) return 0;
int[] dp = new int[s.length()];
int res = 0;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && s.charAt(i) == ')') {
if (s.charAt(i - 1) == '(') {
dp[i] = (i - 2 >= 0 ? dp[i - 2] + 2 : 2);
} else if (s.charAt(i - 1) == ')' && i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
dp[i] = dp[i - 1] + 2 + (i - dp[i - 1] - 2 >= 0 ? dp[i - dp[i - 1] - 2] : 0);
}
}
res = Math.max(res, dp[i]);
}
return res;
}
}
[LeetCode] 32. 最長有效括號