(Java)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.


这道题是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 stub
		int 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。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值