返回
用动态规划解决 leetcode 中的「最长有效括号」难题
前端
2024-02-24 01:27:12
最长有效括号:破解破解括号匹配的奥秘
序幕:理解问题本质
在「最长有效括号」难题中,我们被赋予一个只包含 '(' 和 ')' 的字符串,目标是找到字符串中最长的有效括号子串。所谓有效括号子串,是指左括号 '(' 和右括号 ')' 成对出现,且满足这样的条件:每个左括号都与它右侧的第一个右括号匹配。
例如,在字符串 "(()())" 中,最长的有效括号子串是 "()()"。而在字符串 "((()))))" 中,最长的有效括号子串是 "()()()”。
第一幕:动态规划的闪亮登场
动态规划是一种强大的算法范式,非常适合解决这类子问题相互重叠的问题。在「最长有效括号」难题中,我们可以定义一个状态 dp[i],其中 i 表示字符串的索引,dp[i] 表示从字符串的开头到索引 i 为止的最长有效括号子串的长度。
然后,我们可以根据以下状态转移方程来计算 dp[i]:
- 如果 s[i] 为 '(',则 dp[i] = 0,因为左括号本身不能构成有效括号子串。
- 如果 s[i] 为 ')',则有两种情况:
- 如果 s[i-1] 为 '(',则 dp[i] = dp[i-2] + 2,因为我们找到了一个新的有效括号子串。
- 如果 s[i-1] 为 ')’,则我们需要检查 s[i-1] 之前的括号是否匹配。如果匹配,则 dp[i] = dp[i-1] + dp[i-2] + 2,因为我们找到了一个新的更长的有效括号子串。否则,dp[i] = 0。
第二幕:代码片段的闪亮登场
def longestValidParentheses(s):
"""
:type s: str
:rtype: int
"""
n = len(s)
dp = [0] * n
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
第三幕:优化与改进:锦上添花
为了进一步优化算法的性能,我们可以使用一些额外的技巧和优化方法:
- 空间优化: 我们可以使用一个变量来存储当前最长有效括号子串的长度,而不是存储整个 dp 数组。这将大大降低算法的空间复杂度。
- 剪枝: 在计算 dp[i] 时,我们可以使用剪枝来减少不必要的计算。例如,如果我们已经知道 dp[i-1] = 0,那么我们就无需计算 dp[i]。
- 并行计算: 如果我们有多个处理器,我们可以使用并行计算来加快算法的运行速度。
尾声:掌握动态规划,开启算法新境界
「最长有效括号」难题只是动态规划众多应用场景中的一个示例。通过理解和掌握动态规划的精髓,您将能够解决更多复杂的问题,并成为一名更强大的算法工程师。
最后,希望这篇文章能够帮助您理解和解决「最长有效括号」难题。如果您有任何疑问或建议,请随时与我联系。