LeetCode32:Longest Valid Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

Example 1:

Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"

Example 2:

Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"

LeetCode:链接

解题思路:返回括号串中最长合法括号串的长度。

第一种方法:使用栈。

(1)我们用一个储存字符串的下标索引,用于后期的长度的推算。
(2)遇到 '(' 进栈,遇到 ')' 出栈,在出栈的时候要分情况谈论。
(3)当遇到 ')' 就出栈,如果此时,出栈后,栈已经为空,那么就把当前 i 值(位置索引)放入栈中,相当于入栈了一个')',为什么?它可以作为一个新子串的开始,用于后期合法子串的长度的计算
(4)当遇到 ')' 就出栈,如果此时,出栈后,栈不为空,当前合法子串长度为:i - stack[-1],为什么是 i - stack[-1]?这个很好理解,stack[-1]是栈顶元素,即离当前合法子串左边最近的一个字符,i 是当前位置的索引,也就是 ')' 的位置,所以差就是合法子串的长度,随着不断进栈或者出栈,长度也会发生变化,我们保留最长的一个就可以了。

class Solution(object):
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        stack = [-1]
        maxlen = 0
        for i in range(len(s)):
            if s[i] == '(':
                stack.append(i)
            else:
                stack.pop()
                # 如果栈为空,当前位置索引进栈,做为一个新的子串的开始
                if not stack:
                    stack.append(i)
                else:
                    # 更新合法子串的长度
                    maxlen = max(maxlen, i - stack[-1])
        return maxlen

第二种方法:DP。和LeetCode5:Longest Palindromic Substring思路一样。

(1)设 dp[i] 表示以第i个字符结尾的最长合法字串的长度,初始化全为0。比如"()()()(()())"的dp结果就是02 04 06 0020412。
(2)对整个字符串进行一次遍历操作,遇到 '(' 时,不用操作,因为以 '(' 结尾的子串一定不是合法的
(3)当遇到的字符是 ')' 时,要具体分析,因为以 ')' 结尾的串可能是合法的也可能是不合法的
        A、如果 s[i-1] == '(' 则,dp[i] = dp[i-2] + 2 ,因为前一个是非法结尾,可以形成一对合法的括号,所以直接加2。
        B、如果 s[i-1] == ')' 则,在当前字串前,可能存在一个合法的子串,也可能不存在合法的子串。现在我们要找到 s[i - 1 - dp[i - 1]] 这个字符,判断它是否=='(',如果等于还可以是合法的。
             a、在 s[i - 1 - dp[i - 1]] =='(' 的位置之前,如果也存在一个合法的子串,那么现在也应该把他添加到 dp[i] 中,所以 dp[i] = dp[i - 1] + dp[i - dp[i - 1] - 2] + 2。
             b、否则就是直接在两端添加一对括号,所以总的长度增加 2,dp[i] = dp[i - 1] + 2。

需要注意的是,要判断向前查找的过程,数字不要越界。

class Solution(object):
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        dp = [0] * len(s)
        res = 0
        for i in range(len(s)):
            if s[i] == ")":   # 只考虑以')'结尾的子串
                if i-1 >= 0 and s[i-1] == "(":  # 第一种情况,直接加2
                    dp[i] = dp[i-2] + 2         
                elif i >= 1 and s[i-1] == ")":  
                    # 第二种情况
                    if i-1-dp[i-1] >= 0 and s[i-1-dp[i-1]] == "(":
                        # 当前合法子串,前面还有子串的情况 "()()()(()())" 02 04 06 0020412
                        if i-1-dp[i-1]-1 >= 0:
                            dp[i] = dp[i-1] + dp[i-1-dp[i-1]-1] + 2
                         # 当前合法子串,前面没有子串的情况
                        else:
                            dp[i] = dp[i-1] + 2
                res = max(res, dp[i])
        return res

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值