最长有效括号

给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:

输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”

示例 2:

输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution:
    def longestValidParentheses(self, s: str) -> int:
        def test(temp1):
            left2=0
            right2=0
            for j in temp1:
                if j=='(':
                    left2+=1
                else:
                    right2+=1
                if left2<right2:
                    return False
            return True
        n=len(s)
        if n==0:
            return 0
        left=0
        right=0
        temp=[]
        max_len=0
        for i in range(n):
            if s[i]=='(':
                left+=1
                temp.append(s[i])
            else:
                right+=1
                temp.append(s[i])
            if left<right:
                temp=[]
                left=0
                right=0
                continue
            left1=left
            right1=right
            temp1=temp[:]
            while   (temp1 and  left1!=right1) or ((not test(temp1))and (temp1)):
                if temp1.pop(0)=="(":
                    left1-=1
                else:
                    right1-=1
            if  left1==right1 and len(temp1)>max_len :
                max_len=len(temp1)        
        return max_len

这道题一开始我的思路,是先遍历一遍比如遍历到i时我们就来寻找以s[i]为结尾的有效括号子串的长度。
刚开始我寻找的思路是对以s[i]结尾的子串进行两道排查
1.首先在前面我统计了“(”和“)”的个数,分别为left和right,然后我们在该字串不停的踢出串首字符,同时记录left和right
2.当他们相等时我们需要进行第二道判断,即从头读取一遍该删减过的字符串看看是否会出现left<right的情况假如出现了则说明该子串包含不有效子串“)(”,我们需要把它放到循环里继续从串首踢出元素。

class Solution:
    def longestValidParentheses(self, s: str) -> int:
        n=len(s)
        dp=[0]*n
        max_len=0
        for i in range(n):
            if s[i]=='(':
                dp[i]==0
            elif i-dp[i-1]-1==0and s[0]=='(':
                dp[i]=dp[i-1]+2
            elif i-dp[i-1]-1>0and s[i-dp[i-1]-1]=='(':
                dp[i]=dp[i-1]+2+dp[i-dp[i-1]-2]
            if dp[i]>max_len:
                max_len=dp[i]
        return max_len

由于上一种方法的时间复杂度不符合要求,我们俩用时间换空间,我的想法是当我们遍历到i时我们要判断以s[i]为串尾的有效字串的长度时,我们可以利用之前保存的j<i以是s[j]结尾的字符串的的有效子字符串的长度来判断以s[i]结尾的字符串的有效子字符串的长度。
假如s[i]"("那么肯定不存在以s[i]结尾的有效子字符串
如果是s[i]
")"
我们发现公式dp[i]=dp[i-1]+2+dp[i-dp[i-1]-2]
而当 i-dp[i-1]-1==0时由于dp[i-dp[i-1]-2]不存在所以单独考虑,但由于dp[-1]等于零后来我又把他们这两种情况结合到了一起

class Solution:
    def longestValidParentheses(self, s: str) -> int:
        n=len(s)
        dp=[0]*n
        max_len=0
        for i in range(n):
            if s[i]==')':
                # if i>0and s[i-1]=='(':
                #     dp[i]=dp[i-2]+2
                if  i-dp[i-1]-1>=0and s[i-dp[i-1]-1]=='(':
                    dp[i]=dp[i-1]+2+dp[i-dp[i-1]-2]
            if dp[i]>max_len:
                max_len=dp[i]
        return max_len
class Solution:
    def longestValidParentheses(self, s: str) -> int:
        n=len(s)
        dp=[0]*n
        max_len=0
        for i in range(n):
            if s[i]==')':
                if i>0and s[i-1]=='(':
                    dp[i]=dp[i-2]+2
                elif  i-dp[i-1]-1>=0and s[i-dp[i-1]-1]=='(':
                    dp[i]=dp[i-1]+2+dp[i-dp[i-1]-2]
            if dp[i]>max_len:
                max_len=dp[i]
        return max_len

还有一种思路是,建立一个栈然后进行遍历,假如s[i]"(",则在栈中记录一个点位等待“)”与其配对
如果s[i]
")“那麽我们需要从栈中将与s[i]最近的记录的点删除,表示这之间是有效括号子串,并且记录该长度。
由于假如s[i]")"我们就需要从栈中踢出一个与其对应的点,而当栈中没有与其对应的点的时候即stack为空的时候我们就无法踢出元素了或者假如前面所有的“(”都被消耗完了,这时候我们找不到一个标准来计算出i与最近删除的点之间的长度,wile解决这个问题我们设置一个初始的量度-1
还有当我们stack中只剩下-1而且是s[i]
”)"那么我们需要将-1踢出并且使i成为新的那个量度因为不存在以“)”开头的有效括号。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值