LeetCode OJ算法题(三十一):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、在堆栈为空时遇到“)”,这种情况说明包含这个字符在内的子串是不可能满足题目要求的,于是它可以作为字符串的一个分割点,分别找到他前面和后面的最长匹配子串做比较即可。

2、字符串完结时堆栈中还有“(”,这表示有“(”没有得到匹配,例如(()(),这个时候第一个“(”也是一个分隔符。

接下来我们观察())()(()()((),发现整个字符串被分割为4部分,我们需要计算这四部分的长度,找出最长的一个。

于是我们可以把“(”的下表作为压入堆栈的值,而并非“(”本身,这样在遇到第2种情况时,只需计算堆栈中每个元素之间的差值就可以知道子串的长度了。另外,对于栈底的元素,应该和最近的一个多余“)”的位置做比较,这样就可以统计出第一个没有得到匹配的“(”之前合法的字长长度。而对于栈顶的元素,至于计算字符串末尾和栈顶元素的差就可知道最后一个失配的“(”后面还有多长的合法字符串了。

当遇到第1种情况时,我们也至于要计算这个“)”与上一个失配的“)”之间的距离即可。

代码如下:

import java.util.Stack;


public class No31_LongestValidParentheses {
	public static void main(String[] args){
		System.out.println(longestValidParentheses(")()(()))))"));
	}
	public static int longestValidParentheses(String s) {
        Stack<Integer> stk = new Stack<Integer>();
        int startPos = -1;
        int ret = 0;
        int result = 0;
        for(int i=0;i<s.length();i++){
        	char c = s.charAt(i);
        	if(c == '(')
        		stk.push(i);
        	else if(c == ')'){
        		if(stk.empty()){
        			startPos = i;
        			result = result>=2*ret?result:2*ret;
        			ret = 0;
        			continue;
        		}
        		else if(!stk.empty()){
        			stk.pop();
        			ret++;
        		}
        	}
        }
        if(stk.empty())
        	return result>=2*ret?result:2*ret;
        int endPos = s.length();
        while(!stk.empty()){
        	int t = stk.pop();
        	result = result>(endPos-1-t)?result:endPos-1-t;
        	endPos = t;
        }
        result = result>(endPos-1-startPos)?result:endPos-1-startPos;
        return result;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值