LeetCode 题目 32:最长有效括号【python】

简介: LeetCode 题目 32:最长有效括号【python】

作者介绍:10年大厂数据\经营分析经验,现任大厂数据部门负责人。

会一些的技术:数据分析、算法、SQL、大数据相关、python

欢迎加入社区:码上找工作

作者专栏每日更新:

LeetCode解锁1000题: 打怪升级之旅

python数据分析可视化:企业实战案例

备注说明:方便大家阅读,统一使用python,带必要注释,公众号 数据分析螺丝钉 一起打怪升级

问题描述

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

示例 1

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

示例 2:

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

示例 3:

输入:s = ""
输出:0

这个问题可以通过几种不同的方法来解决,包括动态规划、栈和不使用额外空间的扫描法。

方法一:动态规划

动态规划是解决此类问题的一个非常直观的方法。我们可以定义一个 dp 数组,其中 dp[i] 表示以 s[i] 结尾的最长有效括号的长度。

实现步骤

  1. 初始化:创建一个长度为 n+1 的数组 dp,所有值初始化为 0。
  2. 状态转移
  • 如果 s[i]')'s[i-1]'(',则 dp[i] = dp[i-2] + 2
  • 如果 s[i]')'s[i-1]')'s[i-dp[i-1]-1]'(',则 dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2
  1. 计算结果:最大值在 dp 数组中取得。

代码示例

def longestValidParentheses(s):
    n = len(s)
    dp = [0] * (n + 1)
    max_length = 0
 
    for i in range(1, n):
        if s[i] == ')':
            if s[i-1] == '(':
                dp[i] = dp[i-2] + 2
            elif i - dp[i-1] > 0 and s[i - dp[i-1] - 1] == '(':
                dp[i] = dp[i-1] + dp[i - dp[i-1] - 2] + 2
            max_length = max(max_length, dp[i])
 
    return max_length

方法二:栈

使用栈是另一种常见的解决方案,可以有效地追踪未匹配的括号。

实现步骤

  1. 初始化栈:栈中预先压入 -1,表示最后一个未匹配的右括号的位置。
  2. 遍历字符串
  • 如果 s[i]'(',将 i 压栈。
  • 如果s[i]')'
  • 弹出栈顶元素。
  • 如果栈为空,将当前索引 i 压栈。
  • 如果栈不为空,更新结果 max_length = max(max_length, i - stack[-1])

代码示例

def longestValidParentheses(s):
    max_length = 0
    stack = [-1]
 
    for i in range(len(s)):
        if s[i] == '(':
            stack.append(i)
        else:
            stack.pop()
            if not stack:
                stack.append(i)
            else:
                max_length = max(max_length, i - stack[-1])
    
    return max_length

方法三:不使用额外空间的扫描法

实现步骤

  1. 第一遍扫描(从左到右):
  • 初始化两个计数器left 为左括号计数器,right 为右括号计数器,初始化为0。
  • 遍历字符串:对字符串s的每一个字符进行遍历。
  • 增加计数器:如果字符是 '(',增加 left 计数器;如果字符是 ')',增加 right 计数器。
  • 计算有效长度
  • left 计数器等于 right 计数器时,计算当前有效的括号长度,即 2 * right(或 2 * left,因为此时 left == right),并更新最大长度 maxlength
  • 如果 right 计数器大于 left 计数器,说明括号已经无法闭合,需要重置两个计数器为0,重新开始计数。
  1. 第二遍扫描(从右到左):
  • 重新初始化计数器:同样,leftright 初始化为0,但此次遍历的目的是捕捉如 (() 这类左括号多于右括号的情况。
  • 逆向遍历字符串:从字符串的最后一个字符向前遍历。
  • 增加计数器:如果字符是 '(',增加 left 计数器;如果字符是 ')',增加 right 计数器。
  • 计算有效长度
  • left 计数器等于 right 计数器时,计算当前有效的括号长度,即 2 * left,并更新最大长度 maxlength
  • 如果 left 计数器大于 right 计数器,说明左括号过多,括号无法闭合,需要重置两个计数器为0,重新开始计数。

代码示例

def longestValidParentheses(s):
    left = right = maxlength = 0
 
    # Left to right
    for char in s:
        if char == '(':
            left += 1
        else:
            right += 1
        if left == right:
            maxlength = max(maxlength, 2 * right)
        elif right > left:
            left = right = 0
 
    left = right = 0
    # Right to left
    for char in reversed(s):
        if char == '(':
            left += 1
        else:
            right += 1
        if left == right:
            maxlength = max(maxlength, 2 * left)
        elif left > right:
            left = right = 0
 
    return maxlength

总结

选择哪种方法取决于具体的应用场景和空间时间的权衡:

  • 如果内存资源不是问题,可以优先考虑使用 动态规划 方法,因为它们易于实现和理解。
  • 如果需要优化空间消耗,双向扫描 提供了一个不使用额外空间的有效解决方案。

以上分析展示了每种方法在解决 "最长有效括号" 问题时的性能和适用性,可以根据实际需求灵活选择最合适的方法。


欢迎关注微信公众号 数据分析螺丝钉

相关文章
|
7天前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
1月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
1月前
|
算法 C++
Leetcode第二十二题(括号生成)
这篇文章讨论了如何使用递归算法解决LeetCode第22题“括号生成”的问题,提供了两种C++的实现方法,目的是生成所有有效的括号组合。
14 0
Leetcode第二十二题(括号生成)
|
1月前
|
存储 C++ 容器
Leetcode第二十题(有效的括号)
这篇文章介绍了如何使用栈来解决LeetCode第20题“有效的括号”问题,提供了两种方法:数组栈和容器栈,以及相应的C++代码实现。
16 0
|
1月前
|
Java C++ Python
【面试宝典】深入Python高级:直戳痛点的题目演示(下)
【面试宝典】深入Python高级:直戳痛点的题目演示(下)
|
1月前
|
设计模式 Unix Python
【面试宝典】深入Python高级:直戳痛点的题目演示(上)
【面试宝典】深入Python高级:直戳痛点的题目演示(上)
|
3月前
|
算法
LeetCode第22题括号生成
该文章介绍了 LeetCode 第 22 题括号生成的解法,通过回溯算法生成所有可能的括号组合,在递归过程中根据左右括号数量的条件进行剪枝,从而得到有效的括号组合。
LeetCode第22题括号生成
|
2月前
|
SQL Oracle 关系型数据库
CASE WHEN 语句的语法及示例,LeetCode 题目 “确认率” 练习
本文介绍了SQL中CASE语句的两种形式和语法,并通过LeetCode题目“确认率”的SQL查询示例展示了CASE语句在实际问题中的应用,解释了如何使用CASE语句计算特定条件的比率。
|
3月前
|
存储 算法
LeetCode第20题有效的括号
该文章介绍了 LeetCode 第 20 题有效的括号的解法,通过分析有效括号的特征,使用栈结构存储括号关系,判断遇到右边括号时栈顶是否有匹配的左边括号,从而解决问题,同时总结了栈的先进后出结构可用于解决有规律的符号匹配问题。
LeetCode第20题有效的括号