*LeetCode--32. Longest Valid Parentheses(最长括号匹配长度)
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.
原来想的是
如果为左侧括号,那么入栈,长度+1;
若为右括号,如果栈内还有左括号,则出栈左括号,长度+1;
否则,当前括号组合结束,和最长的进行比较;
发现上面的方法不正确!!!,例如这种情况:()((()) 我们会得到长度是7,然而,最长的是4。这是因为()((()) 中间那个红色的左括号将两边隔开了。
正确的方法:还是分别处理左右括号。
设置一个栈,存放当前长度。
只有左右括号匹配的时候,才将长度一次性+2;
如果是左括号,那么currlen=0,并将currlen入栈。
如果是右括号,若长度栈内没有元素,说明没有左括号与之匹配,currlen=0
若长度栈内有元素,说明有左括号与之匹配,currlen+=2,并与maxlen比较。
public static void main(String[] args) { System.out.println(longestValidParentheses("()((())")); } public static int longestValidParentheses(String s) { Stack<Integer> stack = new Stack<Integer>(); int len = s.length(); int currlen = 0; int maxlen = 0; char c ; for(int i = 0 ; i < len ; i++){ c = s.charAt(i); if(c=='('){ stack.add(currlen); currlen = 0; //只要有分隔开的括号,那么当前这段的长度就是从0开始计算。如果能消除分隔,那么可以将长度相加 } else{ if(stack.isEmpty()) currlen = 0; else{ currlen = currlen + stack.pop() + 2; if(currlen>maxlen) maxlen = currlen; } } } return maxlen; }
方法2:动态规划 (答案来自leetcode讨论区) https://leetcode.com/discuss/24045/simple-java-solution

//DP,实质上和栈的原理差不多 public static int longestValidParentheses3(String s) { char[] S = s.toCharArray(); int[] V = new int[S.length]; int open = 0; //看左括号是否比右括号多 int max = 0; for (int i=0; i<S.length; i++) { if (S[i] == '(') open++; if (S[i] == ')' && open > 0) { //有一对匹配的括号 V[i] = 2 + V[i-1]; if(i-V[i] >= 0) { //看是否能和前面的长度相加。如果i-V[i]位置是左括号,则V[i-V[i]]=0不影响.若不是,那么可以将长度叠加 V[i] += V[i-V[i]]; } open--; } if (V[i] > max) max = V[i]; } return max; }

浙公网安备 33010602011771号