返回
算法必刷题[83]: 获取一个字符串的最大有效括号长度
前端
2023-12-23 17:59:29
正文
在计算机编程中,算法是非常重要的一个环节。算法可以帮助我们快速有效地解决问题,并优化程序的运行效率。在算法的学习中,刷题是一个非常有效的方法。通过刷题,我们可以巩固所学知识,提升解决问题的能力,还能积累经验,为未来的工作打下坚实的基础。
今天,我们来刷一道经典的算法题,也是 LeetCode 上非常受欢迎的一道题:最长有效括号。
题目
给你一个只包含左括号和右括号的字符串,返回它最长的有效括号子序列的长度。
示例 1:
输入:s = ")()())"
输出:4
解释:最长有效括号子序列是 "()()"
示例 2:
输入:s = "(()"
输出:2
解释:最长有效括号子序列是 "()"
示例 3:
输入:s = ""
输出:0
解释:没有有效括号子序列
解题思路
这道题可以用动态规划来求解。我们定义一个状态 dp[i],表示以第 i 个字符结尾的最长有效括号子序列的长度。那么,我们可以根据第 i 个字符是左括号还是右括号来更新 dp[i] 的值。
- 如果第 i 个字符是左括号,那么 dp[i] 为 0,因为左括号无法匹配右括号,所以以第 i 个字符结尾的最长有效括号子序列的长度为 0。
- 如果第 i 个字符是右括号,那么我们首先要检查第 i-1 个字符是否为左括号。如果是,那么 dp[i] 为 dp[i-2] + 2,因为我们可以把第 i-1 个左括号和第 i 个右括号匹配起来,并把它们前面的有效括号子序列也计入其中。如果第 i-1 个字符不是左括号,那么 dp[i] 为 0,因为无法匹配。
下面是动态规划的代码实现:
def longest_valid_parentheses(s):
"""
:type s: str
:rtype: int
"""
n = len(s)
dp = [0] * n
for i in range(1, n):
if s[i] == ')':
if s[i-1] == '(':
dp[i] = dp[i-2] + 2
elif i >= 2 and s[i-1] == ')' and s[i-2] == '(':
dp[i] = dp[i-2] + dp[i-3] + 2
return max(dp)
# 测试代码
print(longest_valid_parentheses(")()())")) # 4
print(longest_valid_parentheses("(()")) # 2
print(longest_valid_parentheses("")) # 0
复杂度分析
- 时间复杂度:O(n),其中 n 为字符串 s 的长度。
- 空间复杂度:O(n),其中 n 为字符串 s 的长度。
结语
这道题是算法必刷题中的经典题型,希望大家能够通过这道题的讲解,对动态规划算法有更深入的理解。刷题虽然重要,但更重要的是要理解算法背后的思想和原理,这样才能举一反三,触类旁通。祝大家刷题愉快!