32. 最长有效括号
Posted 2016bits
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了32. 最长有效括号相关的知识,希望对你有一定的参考价值。
一、题目描述
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
二、实例
示例 1:
输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"
示例 3:
输入:s = ""
输出:0
补充示例 4:
输入:s = "(()())"
输出:6
补充示例 5:
输入:s = "((()))"
输出:6
三、输入输出说明
0 <= s.length <= 3 * 104
s[i] 为 '(' 或 ')'
四、基本思路
1、栈
遇到左括号则进栈,遇到右括号则出栈。由于统计最长有效括号,所以形如"()()"这种,会经历连续两次进栈出栈,则设置start记录最开始的位置。在这种情况下,遇到左括号进栈无影响,遇到右括号出栈则需要分情况讨论:
若出栈之前栈内已无元素,则更新start为当前位置的下一位置,最长序列长度不变;
若出栈时栈内有元素,则先出栈,若出栈之后栈内无元素,则当前序列长度为start与当前索引之间的距离(i - start + 1)(此时序列长度包含start位置的元素,所以需要+1),同时更新最长序列长度
若出栈之后栈内仍有元素,则当前序列长度为栈顶元素st.top()与当前索引之间的距离(i - st.top())(此时序列长度不包含栈顶元素,所以不需要+1),同时更新最长序列长度
2、动态规划
使用动态规划时主要需要考虑后续问题如何利用之前问题的解,在本问题中则需要考虑如何增长有效括号的长度。主要分为以下两种情况:(使用数组dp[i]记录从第一个符号到索引为i位置处最长有效括号的长度)
- "(())":当i为0和1处的dp[i]均为0,到达索引为i=2的位置,由于i-1处为左括号,i处为右括号,此时可以增长有效括号长度:dp[i] = dp[i-1] + 2(前一位置的最长长度加上新增的括号对,长度加2)。当索引i=3时同样适用。
- "()()":此时为括号并列的情况,此时需要寻找在匹配了当前右括号(i=3)的左括号(i=2)的前一位置(i=1),若此位置存在,则加上该位置(i=1)的最长长度:dp[i] += dp[i - 1 - dp[i-1] - 1](对比示例仔细考虑索引关系)
五、代码
1、栈
class Solution
public:
int longestValidParentheses(string s)
if (s == "")
return 0;
int start = 0;
int ans = 0;
stack<int> st;
for (int i = 0; i < s.length(); i++)
if (s[i] == '(')
st.push(i);
else if (st.empty())
start = i + 1;
continue;
else
st.pop();
if (st.empty())
ans = max(ans, i - start + 1);
else
ans = max(ans, i - st.top());
return ans;
;
2、动态规划
class Solution
public:
int longestValidParentheses(string s)
if (s == "")
return 0;
int ans = 0;
int len = s.length();
int* dp = new int[len]();//创建长度为s.length(),初始值为0的数组
for (int i = 1; i < len; i++)
int left = i - 1 - dp[i-1];
if (s[i] == ')' && left >= 0 && s[left] == '(')
dp[i] = dp[i-1] + 2;
if (left - 1 >= 0)
dp[i] += dp[left-1];
ans = max(ans, dp[i]);
return ans;
;
以上是关于32. 最长有效括号的主要内容,如果未能解决你的问题,请参考以下文章
32.最长有效括号(Longest Valid Parentheses)