(Java)LeetCode-32. Longest Valid Parentheses

来源:互联网 发布:mac调用finder快捷键 编辑:程序博客网 时间:2024/05/16 04:55

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.


这道题是Hard模式,写了一晚上终于Accept了,好开心啊。

不过之后上网看了看别人的想法,自己还是naive了一些,该简单的地方让我弄复杂了,借鉴借鉴。我的代码如下:

PS 不过也弄清楚了LeetCode评判系统会一遍一遍的调用你的函数,所以我依赖一个类中的静态变量的话,每次都需要重置,要不会一直增加下去~

package datastru;import java.util.Stack;public class Solution {public int longestValidParentheses(String s) {    if(s.length() == 0){return 0;}    if(s.indexOf(")") == -1){    return 0;    }char[] ch = s.toCharArray();boolean[] sit = new boolean[ch.length];Stack<LeftParenthese> stack = new Stack<LeftParenthese>();int max = 0;int max_temp = 0;int le = 0;int ri = 0;boolean flag = false;for(char c : ch){if(c == '('){LeftParenthese left = new LeftParenthese();stack.push(left);ri = left.getIndex();flag = true;}else{if(!stack.isEmpty()){LeftParenthese left = stack.pop();sit[left.getIndex()] = true;}else{max_temp = calmaxlength(sit,le,ri);if(max_temp > max)max = max_temp;if(flag)le = ri+1;}}}max_temp = calmaxlength(sit,le,ri);if(max_temp > max)max = max_temp;//LeftParenthese.resetStatic();        return max;    }public static void main(String[] args){    Solution sol = new Solution();    String str = ")()())()()(";    System.out.println(sol.longestValidParentheses(str));}private int calmaxlength(boolean[] sit, int le, int ri) {// TODO Auto-generated method stubint max_length = 0;int temp_length = 0;for(int i = le; i <=ri; i++){if(sit[i] == true){temp_length++;}else{if(temp_length > max_length){max_length = temp_length;}temp_length = 0;}}if(temp_length > max_length){max_length = temp_length;}return max_length * 2;}}class LeftParenthese{private static int static_index = 0;private int index;public LeftParenthese(){index = static_index++;}public int getIndex(){return index;}public static void resetStatic(){static_index = 0;}}


虽然我也考虑到了用每个符号的index来进栈,但是我是只统计了已经配对的 "(" 的序号,有几个连续的已配对的 "(" ,该有效括号长度就是 "(" 个数的二倍。还有入栈我新建了一个对象,里面存的index,大可不必如此,就用一个int就可以了,这样反而拖累了速度。

其实呢有更好的方法,可以用配对成功的 ")" 的序号来减去栈中还有的 "("的序号来获得长度的,哎,当时没想到啊。失误失误,摘自别人博客的思路如下:

想要O(n)的解法需要一点技巧,栈中保存的不是‘(’而是‘(’所在的index,在此基础上也要弄清楚几种情况:
每次来了‘(’之后,无条件压栈。如果碰到')'的话,如果栈不为空,就消除栈内剩余的'('
第一:消除掉'('之后,如果栈内还有剩余的‘(’的话,最长的合法长度就是:maxLength = Math.max(i - (int)stack.peek() , maxLength);  也就是取:当前')'的index减去栈顶元素的index  和 原来max_length 两者的最大值。

例如:对于这种情况:()(()(),可以正确的得出最大值为4。

第二:消除掉')'之后,栈内没有剩余的‘(’了。此时需要引入一个新的变量start,用于表示合法括号字符串的起点。
例如:对于这种情况:())()(),可以正确的得出最大值为4。

start初始为-1,之后每次碰到‘)’且栈为空的时候更新为当前‘)’的index。也就是说无法消除的)之后的括号不可能再和前面的括号合并在一起计算最长序列,所以更新start。


0 0
原创粉丝点击