【leetcode】Longest Valid Parentheses 详细讲解

题目:给定一串仅由' ( '和 ' )'组成的括号字符串s,由于整个括号串可能不全部匹配,但可能存在部分匹配,返回匹配的最长的括号数。

分析:注意题目中红色加粗的部分,它给我们解这道题带来了很大的便利,因为在当前访问到‘)’ 时,我们不用去判断栈顶元素是否为 ‘(’,因为没有除二者之外的字符,‘)’又不入栈,所以只要判断当前栈不空,那么就肯定是‘(’,肯定就是一个匹配的括号对。

由于要返回的是最大匹配长度,栈又只需要判断是否为空,我们向栈里压入什么呢?对,就是元素的下标。这样一来,我们就可以利用栈顶元素的下标来计算最长匹配了。

在任何时候,只要栈不空,那么存在栈里的元素的意义就是当前尚未被匹配的‘(’。因为若匹配,我们会进行pop操作,所以在进行一次匹配后,我们若判断栈不空,那就说明至少栈顶的元素是没有匹配的,而这个没有匹配的栈顶‘(’,极有可能到最后也得不到匹配,所以我们这时要及时的更新最大长度,那么当前的已经匹配的长度是多少呢?是当前访问元素的index - 栈顶元素的值。若进行一次匹配操作后,发现栈为空了,这说明什么呢?说明是处于连续的匹配中,这时我们也要跟新最大长度,因为极有可能在以后就不匹配了,当前这个匹配的最大结果要进行保留。但是此时,我们只有当前遍历元素的下标,另外一个值是什么呢?也就是减数是多少呢?所以我们还需要定义一个变量,用来表示每一次连续匹配的起始点,我们用当前的下标- 起始点 + 1 来表示当前的最大长度。那么若当前遍历的元素为‘)’,且此时栈为空,说明什么呢?说明在此之前,就没有多余的‘(’,说明这就是个坑,是个不匹配的点,此时我们要做些什么呢?简单的将该字符跳过,去处理下一个字符吗?回头看看我们刚才分析中,涉及到了一个连续匹配的起始点问题,对,我们要更改这个连续匹配的起始点,令其等于当前处理的‘)’字符的下一位置。

好了,经过这样的分析,代码就呼之欲出了。

//CODE

int longestValidParentheses(string s) {

		if(s.size() <= 1) return 0;
		int len = s.size();

		//container to store the index of '('s in s
		//which haven't been matched.
		stack<int> cs;
		int max_length = 0;
		int index = 0;
		//the start of the match sequence.
		int imatch = 0;

		const char left_parentheses = '(';
		const char right_parentheses = ')';
	    
		while (index < len )
		{
			if(s[index] == left_parentheses){
				cs.push(index++);
				continue;
			}
			else{//right_parentheses
				if(!cs.empty())//the top must be '('
				{
					cs.pop();//the top '(' has been matched, pop it.
					//there is one '(' that unmatched.
					//it's a potential unmatched '(', update the matched length in time
					if(!cs.empty())
						max_length = max(max_length, index - cs.top());
					else
						max_length = max(max_length, index - imatch + 1);
				}
				else //this is no '(' to match.
					imatch = index + 1;
			}
			++index;
		}//end while
	
		return max_length;
	}

说明:涉及最大最小的问题,dp应该可以解决,还没想好,但是觉得应该可以解决,明天吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值