标签:
题目: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.
村翻一下:给定一个只包含‘(‘和‘)‘的字符串,找出最长的括号匹配的子字符串。比如,“(()”,最长的子字符串为“()”,长度为2。再举个栗子,如“)()())”,最长的子字符串为"()()",长度为4。
这题最明显的方法就是搜索,时间复杂度为0(n^2)。明显的方法,肯定是会超时的-_-!
最开始的想法:
我最开始的想法是,先定义一个栈,全部都保存的是‘(‘(实际上这个栈不需要在代码里面用,只是想一下),遇到‘(‘,那么就进栈,如果遇到’)‘并且栈不为空,那么就把括号长度cur加上1。如果遇到‘)‘且栈为空,那么就让cur和max比较,如果比max大,那么就把max赋值为cur。整个方法中,其实不需要用栈,只需要记录‘(‘的个数就可以了,因为整个栈中只有‘("。但是这个方法有个漏洞,就是不能解决形如’(()(()‘这样的括号字符串。按照前面的思路,这个字符串算出来的长度为4,所以上述方法是不行的。不过,这个给我提供了一个好的思路。
使用一个数组。数组中的值为-1,0和子括号字符串的长度。子括号字符串的长度表示一个子括号字符串的长度。。。。-1表示某个位置上为一个‘)‘且没有匹配上‘(‘(如果匹配上的话,那么久会合并计入子括号字符串了)。0表示某个位置上为一个‘(‘且没有任何匹配。比如s="(()(()"这个字符串,队列应该为[0, 2, 0, 2]。第一个0代表了s[0], 第一个2代表了第s[1]开始的“()”子字符串的长度,第二个0代表了s[3], 第二个2代表了第s[4]开始的"()"子字符串。所以该队列保存的就是‘(‘,‘)‘和匹配的子字符串的长度,不过’(‘长度算作0,‘)‘算作-1。
该算法这样运作。使用st记录‘(‘的数目,esp为数组中最后一个元素的下标,a即为前边的数组。开始遍历整个字符串,如果遇到‘(‘,那么就把0加到数组的尾部。如果遇到’)‘且st>0,即前面有匹配的‘(‘,那么就判断数组中最后一个元素是不是为0。如果为0,那么把数组最后一个元素赋值为2(这说明了当前的‘)‘前面刚好是个‘(‘)。如果不为0,那么把数组最后一个元素加二并赋值给倒数第二个元素,然后把最后一个元素弹出数组(这种情况对应了‘)’前面是“(()()”这种‘(’+合法子字符串的情况)。然后,赋值完以后,如果数组尾部的两个元素都不为0,那么就把两个值相加,然后赋值给倒数第二个元素(这代表了两个合法子字符串的合并)。
代码如下:
class Solution(object): def longestValidParentheses(self, s): """ :type s: str :rtype: int """ max = 0 i = 0 st = 0 a =[] esp = -1 for i in range(len(s)): if (s[i] == ‘(‘): a.append(0) esp += 1 st += 1 elif ((s[i] == ‘)‘) & (st > 0)):#有匹配的‘(‘ st -= 1 if (a[esp] == 0): #前边正好是‘)‘ a[esp] = 2 elif ((esp > 0) and (a[esp] >= 0)): #前边是个合法的子字符串,再前边是匹配的‘(‘ a[esp - 1] = a[esp] + 2 a.pop() esp -= 1 else:#不可能的情况 print ‘error\n‘ if ((esp > 0) and (a[esp - 1]>0)): #合并合法的子字符串 a[esp-1] += a[esp] a.pop() esp -= 1 else: a.append(-1) esp += 1 for i in a: if (i > max): max = i return max
Longest Valid Parentheses Leetcode 32 一种奇特的解法
标签:
原文地址:http://www.cnblogs.com/DennisXie/p/4779354.html