原题:Given a string containing just the characters ‘(‘ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
For “(()”, the longest valid parentheses substring is “()”, which has length = 2.
Another example is “)()())”, where the longest valid parentheses substring is “()()”, which has length = 4.
LeetCode:https://leetcode.com/problems/longest-valid-parentheses/
思路:使用动态规划,令s[i]表示字符串的第i个字符,dp[i]表示以s[i]为结束符的最长合法字符串的长度,此题转化成最最大的dp[i]。
dp[]初始化全部都是0。
遍历s,如果s[i]是“(”,那么放入栈中(left自增1),left表示目前可用的“(”数目。
如果s[i]是“)”,并且left大于0,那么可以根据dp之前的值来计算当前的dp。
如果dp[i – 1] == 0,那么s[i – 1]一定是一个“(”。
如果dp[i – 1] != 0,那么s[i – 1] 一定是一个“)”,并且s[i – 1 – dp[i – 1]]一定是一个“(”(即当前栈顶的左括号)。
。
所以无论是dp[i – 1] == 0 还是dp[i – 1] != 0,都有:
dp[i] = dp[i – 1] + 2;
但是我们还漏掉了一种场景,例如以(())为例,它的最左边可能还有(),如()(()),需要把最左边的合法串也加进来。于是有:dp[i] += (i – dp[i]) > 0 ? dp[i – dp[i]] : 0;
public class Solution {
public intlongestValidParentheses(String s) {
int ret = 0;
// dp[i]表示以i为结束符的最长合法字符串
int[] dp = new int[s.length()];
int left = 0; // 可用的 '(' 数目
for (int i = 0; i < s.length(); ++i) {
// 注意这个地方不要把String转化成char数组,否则String太大时会超时!
if (s.charAt(i) == '(') {
++left;
} else {
if (left > 0) {
dp[i] = dp[i - 1] + 2;
dp[i] += (i - dp[i]) > 0 ? dp[i - dp[i]] : 0;
ret = Math.max(ret, dp[i]);
--left;
}
}
}
return ret;
}
public static void main(String[] args) {
Solution s = new Solution();
String str = "()()";
System.out.println(s.longestValidParentheses(str));
}
}