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. 第二遍扫描(从右到左):
  • 重新初始化计数器:同样,left 和 right 初始化为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

总结

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

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

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


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

相关文章
|
人工智能 索引 Python
[oeasy]python091_列表_索引_index_中括号_索引函数
本文介绍了Python中列表与字符串的索引及index函数用法。通过range生成列表,使用索引[]访问和修改列表元素,index函数查找元素位置。字符串支持索引访问但不可直接修改。还探讨了16进制数在Python中的表示方法,以及日期、月份等特殊字符的Unicode范围。最后总结了列表与字符串操作的区别,并预告后续内容,提供蓝桥云课、GitHub和Gitee链接供进一步学习。
484 20
|
算法 Go 索引
【LeetCode 热题100】回溯:括号生成 & 组合总和(力扣22 / 39 )(Go语言版)
本文深入解析了LeetCode上的两道经典回溯算法题:**22. 括号生成**与**39. 组合总和**。括号生成通过维护左右括号数量,确保路径合法并构造有效组合;组合总和则允许元素重复选择,利用剪枝优化搜索空间以找到所有满足目标和的组合。两者均需明确路径、选择列表及结束条件,同时合理运用剪枝策略提升效率。文章附有Go语言实现代码,助你掌握回溯算法的核心思想。
715 0
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
523 4
LeetCode第22题括号生成
该文章介绍了 LeetCode 第 22 题括号生成的解法,通过回溯算法生成所有可能的括号组合,在递归过程中根据左右括号数量的条件进行剪枝,从而得到有效的括号组合。
LeetCode第22题括号生成
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
432 1
|
算法 C++
Leetcode第二十二题(括号生成)
这篇文章讨论了如何使用递归算法解决LeetCode第22题“括号生成”的问题,提供了两种C++的实现方法,目的是生成所有有效的括号组合。
344 0
Leetcode第二十二题(括号生成)
|
存储 算法
LeetCode第20题有效的括号
该文章介绍了 LeetCode 第 20 题有效的括号的解法,通过分析有效括号的特征,使用栈结构存储括号关系,判断遇到右边括号时栈顶是否有匹配的左边括号,从而解决问题,同时总结了栈的先进后出结构可用于解决有规律的符号匹配问题。
LeetCode第20题有效的括号
|
存储 C++ 容器
Leetcode第二十题(有效的括号)
这篇文章介绍了如何使用栈来解决LeetCode第20题“有效的括号”问题,提供了两种方法:数组栈和容器栈,以及相应的C++代码实现。
256 0
|
Java C++ Python
【面试宝典】深入Python高级:直戳痛点的题目演示(下)
【面试宝典】深入Python高级:直戳痛点的题目演示(下)
|
设计模式 Unix Python
【面试宝典】深入Python高级:直戳痛点的题目演示(上)
【面试宝典】深入Python高级:直戳痛点的题目演示(上)

热门文章

最新文章

推荐镜像

更多