DailyChallenge
32. 最长有效括号
20200704
难度:困难
题目描述
给定一个只包含 '('
和 ')'
的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"
Solution
- 栈
class Solution {
public int longestValidParentheses(String s) {
int ans = 0;
Stack<Integer> stack = new Stack<>();
stack.push(-1);
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{
ans = Math.max(ans, i-stack.peek());
}
}
}
return ans;
}
}
- 动态规划
- 状态:
dp[i]
代表以下标i
字符结尾的最长有效括号的长度 - 状态转移:
- 若下标
i
的字符(记为s[i]
)为(
,dp[i] = 0
s[i] == ')'
s[i-1] == '('
时,dp[i] = dp[i-2] + 2
s[i-1] == ')'
时,这时要去除中间已经成为有效括号的部分来看,也就是看s[i-dp[i-1]-1]
是(
还是)
- 若
s[i-dp[i-1]-1] == (
,也就是有效括号的长度还会增加,dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2
。其中dp[i-1]
为中间段,dp[i-dp[i-1]-2] + 2
为两边段。
- 若
- 若下标
- 状态:
class Solution {
public int longestValidParentheses(String s) {
int ans = 0;
int dp[] = new int[s.length()];
for(int i = 1; i < s.length(); i++){
if(s.charAt(i) == ')'){
if(s.charAt(i-1) == '('){
dp[i] = i >= 2 ? dp[i-2] + 2 : 2;
}else if(i-dp[i-1] > 0 && s.charAt(i-dp[i-1]-1) == '('){
dp[i] = dp[i-1] + (i-dp[i-1] >= 2 ? dp[i-dp[i-1]-2] : 0) + 2;
}
ans = Math.max(ans, dp[i]);
}
}
return ans;
}
}
我的公众号:GitKid
暂时每日分享LeetCode,我在不断学习的过程中,公众号也在不断充实,欢迎大家扫码关注。
TODO:动态规划专题