LeetCode32-最长有效括号

最近这两天有断更了,大家知道是为什么吗?肯定不是因为是我懒哈(大家想要笑也要憋着)这两天一直在研究回溯法,被折磨的死去活来的。终于是有些收获了,所以会在这两天再把我的一些关于解回溯法题目的心得分享出来,希望大家会有些收获。写的都会是很通俗易懂的大白话,会教大家怎么写递归的过程,因为回溯法虽然好用,但是如何写出这个过程一直很麻烦,因为其抽象性比较高,很容易就被它搞糊涂了。而我这两天在网上找的资料都是千篇一律,基本上都是把一些现货炒来炒去,害人不浅!!!大家敬请期待我的文章。


32-最长有效括号

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

示例 1:

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

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

这一题算是20题有效的括号进阶版了,因为是要求最长的,所以我们必须是得存储一个字符串中所有有效括号的长度信息,再从里面选取长度最大值即可,这算是最直接的思路了。我第一次也是这样做的。

思路:

  1. 首先用20题求解有效括号的方法(进栈出栈)求得给定字符串中所有有效括号的成对下标值,并保存在一List列表中。
  2. 因为成对括号下标可能相邻也可能相差大于1,但是下标排序后连续且相差1的下标串对应的字符串必然是合法结构,所以我只需要将1中得到的列表中的值做sort()排序操作。
  3. 依次检查相邻下标值相差为1的下标最大个数,取最大值即为所求的最长有效括号的长度

代码如下:

class Solution:
    # 本题还是采用较典型的进栈出栈法
    # 字典再添加元素时key值并不是按照从小到大排列的,顺序是混乱的
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        if len(s) == 0 or len(s) == 1:
            return 0
        s_list = list(s)
        # 定义一个字典用做栈,方便做进栈入栈操作,字典key值为括号对应的下标值,value值为相应的括号
        s_queue = {0: s[0]}
        # 定义一个List列表用于保存一对有效括号的两个下标值
        max_s_length = []
        for s_index in range(1, len(s_list)):
            # 只有当元素为')'才能出栈,此时要比较栈顶元素,
            # 如果栈顶元素也就是s_queue[s_queue_lastkey]为'('则可以出栈,反之则不行
            if len(s_queue) > 0 and s_list[s_index] == ")":
                # 字典再添加元素时key值并不是按照从小到大排列的,顺序是混乱的,所以一定要把key值排序
                # 这样才能每次拿到s_queue字典最后一个值,也就是栈顶元素
                s_queue_keys = list(s_queue.keys())
                s_queue_keys.sort()
                s_queue_lastkey = s_queue_keys[-1]
                print("s_queue_lastkey", s_queue_lastkey)
                # 如果栈顶元素也就是s_queue[s_queue_lastkey]为'('则可以出栈
                if s_queue[s_queue_lastkey] == "(":
                    print("[s_queue_lastkey, s_index]", [s_queue_lastkey, s_index])
                    max_s_length.extend([s_queue_lastkey, s_index])
                    s_queue.pop(s_queue_lastkey)
            # 只有当元素为'('才能进栈,也就是s_queue字典才能保存该key值
            else:
                s_queue[s_index] = s_list[s_index]
                print("s_queue", s_queue)
        # 有效括号的下标值得到后排序,并对里面相邻的值检查,即可得到最大长度值
        # 关键:成对括号下标可能相邻也可能相差大于1,但是下标排序后连续且相差1的下标串对应的字符串必然是合法结构
        max_s_length.sort()
        if len(max_s_length) == 0:
            return 0
        print("max_s_length", max_s_length)
        length = 1
        max_length = 0
        # 遍历max_s_length列表,寻找相差为1的下标的最大个数
        for index in range(1, len(max_s_length)):
            if max_s_length[index] - max_s_length[index-1] == 1:
                length += 1
            else:
                if length > max_length:
                    max_length = length
                length = 1
        return max(length, max_length)


if __name__ == "__main__":
    s = "))(((()()"
    result = Solution().longestValidParentheses(s)
    print(result)

这段代码中我做了很多注解,大家应该挺好看懂的,但是执行效率挺差的,只有10%左右。

LeetCode32-最长有效括号_第1张图片 LeetCode32-最长有效括号_第2张图片

后来在网上看到了一大佬给的算法,也是采用进栈出栈法,但是它是直接将有效括号对的下标值进行运算得到最大有效长度,真的是牛逼,不知道大佬们是怎么能想到这么简单快捷的骚操作,我也把代码贴出来,大家可以学习学习。

class Solution:
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        tl = len(s)
        stack = []
        st = 0
        maxlen = 0
        for i in range(tl):
            # 如果是左括号,直接入stack
            if s[i] == '(':
                stack.append(i)
            # 如果右括号
            else:
                # 如果stack里没有元素匹对,说明有效括号已经结束,更新起始位置
                if len(stack) == 0:
                    st = i + 1
                    continue
                # 有元素匹对
                else:
                    a = stack.pop()
                    # pop出一个左括号匹对
                    # 如果此时没了,不能保证不继续有效括号,所以根据当前的最长距离去更新maxlen
                    if len(stack) == 0:
                        maxlen = max(i - st + 1, maxlen)
                    # 如果此时还有 则计算与栈顶的索引相减来计算长度
                    else:
                        maxlen = max(i - stack[-1], maxlen)

        return maxlen


if __name__ == "__main__":
    s = "))(((()()"
    result = Solution().longestValidParentheses(s)
    print(result)

执行效率也是真的高,再次跪拜大佬!!!

 LeetCode32-最长有效括号_第3张图片

你可能感兴趣的:(LeetCode32-最长有效括号)