zoukankan      html  css  js  c++  java
  • Longest Valid Parentheses Leetcode 32 一种奇特的解法

    题目: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
    '
    			
    		    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
    

      

  • 相关阅读:
    Redis常用命令手册:键值相关命令
    Redis常用命令手册:服务器相关命令
    预览图片插件
    Hibernate的generator属性之意义
    CentOS开机自动运行程序的脚本
    64位Win7安装Oracle12C临时位置权限错误解决方案
    ORACLE基本语法
    linux图形界面安装
    因xhost命令和DISPLAY环境变量操作不当导致无法启动Oracle图形化安装界面
    Linux 配置:Xmanager连接Linux图形界面
  • 原文地址:https://www.cnblogs.com/DennisXie/p/4779354.html
Copyright © 2011-2022 走看看