[Leetcode] 32. Longest Valid Parentheses

本文探讨了如何在包含仅括号的字符串中找到最长的有效括号子串的问题。介绍了两种解决方案,一种是通过暴力方法,另一种是利用栈的数据结构进行优化。详细解释了栈方法的实现步骤,并给出了Python代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem:
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.

Idea:
这道题思路不难得出,但是很容易超时,这也是leetcode里难度为hard的原因。
一开始想到的办法是,直接暴力地两两截取某段substring,判断是否为valid parentheses,一个O(n2)的方法。
更优解是用栈的思想。成功配对的话就pop,不成功就push。但是仍然超时。原因是,我执着于正向计算valid parentheses的区间,而把若干个小的子区间并成大的完整区间比较耗时。

一个比较好的解决办法是,反向计算成功配对的区间。使用栈的方法计算一遍之后(O(n)), 再遍历一遍仍然在栈里面的未匹配成功的元素,从而得知未匹配元素的区间,进而取反求得成功匹配元素的区间。时间复杂度近似为O(n).

Reference:

  1. Scan the string from beginning to end.
  2. If current character is ‘(’,
    push its index to the stack. If current character is ‘)’ and the
    character at the index of the top of stack is ‘(’, we just find a
    matching pair so pop from the stack. Otherwise, we push the index of
    ’)’ to the stack.
  3. After the scan is done, the stack will only
    contain the indices of characters which cannot be matched. Then
    let’s use the opposite side - substring between adjacent indices
    should be valid parentheses.
  4. If the stack is empty, the whole input
    string is valid. Otherwise, we can scan the stack to get longest
    valid substring as described in step 3.

Solution:

一个很酷的python解法
    def longestValidParentheses(self, s):
         stack, res, s = [0], 0, ')'+s
         for i in xrange(1, len(s)):
             if s[i] == ')' and s[stack[-1]] == '(':
                 stack.pop()
                 res = max(res, i - stack[-1])
             else:
                 stack.append(i)
         return res
我的辣鸡解法
class Solution(object):
    def longestValidParentheses1(self, s):
        """
        :type s: str
        :rtype: int
        """
        max_num=0
        i=0
        j=1
        length=len(s)
        l=list()
        if length==0:
            return 0
        else:
            l.append([s[0],0])
            i=0
        while j <length:
            if len(l)==0:
                l.append([s[j],j])
                j+=1
                i+=1
            elif l[i][0]=='(' and s[j]==')':
                l.pop()
                i-=1
                j+=1
            else:
                l.append([s[j],j])
                j+=1
                i+=1
        if len(l)==0:
            return length
        elif len(l)==1:
            return l[0][1] if l[0][1] > length-l[0][1]-1 else length-l[0][1]-1
        else:
            max_num = l[0][1]
        for i in xrange(0,len(l)-1):
            a=l[i][1]
            b=l[i+1][1]
            if b-1 != a:
                max_num = max_num if max_num > b-a-1 else b-a-1
            if i==len(l)-2:
                max_num = max_num if max_num > length-b-1 else length-b-1
        return max_num
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值