最长的括号子串_牛客题霸_牛客网 (nowcoder.com)
一个长度为n的字符串,仅包含字符‘(’ 和 ‘)’ ,计算正确格式的长度
例1: 对于字符串 "(()" 来说,最长的格式正确的子串是 "()" ,长度为 2 .
例2:对于字符串 ")()())" , 来说, 最长的格式正确的子串是 "()()" ,长度为 4
1.栈
class Solution { public: int longestValidParentheses(string s) { int res = 0; //记录上一次连续括号结束的位置 int start = -1; stack<int> st; for (int i = 0; i < s.length(); i++) { //左括号入栈 if (s[i] == '(') st.push(i); //右括号 else { //如果右括号时栈为空,不合法,设置为结束位置 if (st.empty()) start = i; else { //弹出左括号 st.pop(); //栈中还有左括号,说明右括号不够,减去栈顶位置就是长度 if (!st.empty()) res = max(res, i - st.top()); //栈中没有括号,说明左右括号刚好,减去上一次结束的位置就是长度 else res = max(res, i - start); } } } return res; } };
2.动态规划
class Solution { public: int longestValidParentheses(string s) { int res = 0; //长度为0的串,返回0 if(s.length() == 0) return res; //dp[i]表示以下标为i的字符为结束点的最长合法括号长度 vector<int> dp(s.length(), 0); //第一位不管是左括号还是右括号都是0,因此不用管 for(int i = 1; i < s.length(); i++){ //取到左括号记为0,有右括号才合法 if(s[i] == ')'){ //如果该右括号前一位就是左括号 if(s[i - 1] == '(') //计数+2 dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2; //找到这一段连续合法括号序列前第一个左括号做匹配 else if(i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == '(') dp[i] = (i - dp[i - 1] > 1 ? dp[i - dp[i - 1] - 2] : 0) + dp[i - 1] + 2; } //维护最大值 res = max(res, dp[i]); } return res; } };