leetcode第三十二题 —— 最长有效括号

1.题目

原题:

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

例子:

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

2.解析

这道题可以好好盘一盘我的心路历程,里边全是坑,大家注意避着点。
先来说正确解法:栈和动态规划。
栈是这次考虑的重点,动态规划以后有空再补充。

2.1 我的错误做法

当时我思考的栈解决问题,但是我考虑的太复杂了,甚至加了双指针。

  • 疑点1,为啥不用双指针
    答:栈本来就是动态的,可以不断地入栈、出栈,本来就可以记录下标位置。
  • 疑点2,用for循环还是while循环
    答:其实都可以,for循环和while循环一层就可以了,不用考虑正确匹配的开始位置可能是第一个也能是第n个,因为栈可以记录下所有符合条件的括号集合。
  • 疑点3,什么时候进行有效括号的计算
    答:遇到左括号就入栈,这个是肯定的,因为只要是左括号,就可能有有效匹配,因此计算只能出在右括号里。
    右括号也分情况:
  • 第一种是栈空了,注意这个栈空了的意思是没有左括号可以和这个右括号匹配,这个时候观察一下,i - start和当前最大有效括号lk(下面简称lk了)之间的最大值就是此次的lk。
    这里的小疑点,为啥是i- start?因为有效的匹配位置是i-1,思考一下这个)括号不是有效的匹配,有效的匹配只到前一个位置,计算从开始位置到有效位置有多少位,i - 1 - start + 1(1到7有几个数?7-1+1 =7对不对),就是i-start。这个完事之后咱从下一位开始匹配,更新一下start。
  • 第二种是栈没空,到此位置还是有效的,然后我们需要pop掉一个元素。pop完了又出问题了,栈空了,栈没空。(杨宗纬《我变了,我没变》)
    假设栈空了,你能咋办,匹配完了呗,算一下几个括号,i - start + 1,这个不想解释了,参考上面的说法吧。
    假设栈没空,哎没匹配完,有效的有几个啊,注意哦当前i位置是有效的,然后前面pop掉一个i - (stack[-1] + 1) +1 ,嗯算完了i - stack[-1]。stack是啥,你们觉得是啥,当然是左括号对应的下标啊。

2.2 正确做法

做出这道题总共分三步:
第一步,整个循环,遍历输入字符串。
第二步,设置一个start,随时更新着,设置一个stack,记录下左括号的下标。
第三步,开始操作,按照上一节的疑点3操作,对着代码看,可能更清楚一点。

3.python代码

class Solution:
    def longestValidParentheses(self, s):
        nlen = len(s)
        i = 0
        new_stack = []
        lk = 0
        start = 0
        if nlen <= 1:
            return 0
        while i < nlen:
            # print(i)
            # print(new_stack)
            # print('start', start)
            if s[i] == '(':
                new_stack.append(i)
            else:
                if new_stack:
                    new_stack.pop()
                    if new_stack == []:
                        lk = max(lk, i - start + 1)
                    else:
                        # print(2)
                        lk = max(lk, i - new_stack[-1])
                else:
                    lk = max(lk, i - start)
                    start = i + 1
            i += 1
        return lk

你可能感兴趣的:(leetcode第三十二题 —— 最长有效括号)