1. 题目

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

2. 思路

模拟进出栈来计算。但是由于可能遇到后缀不匹配的情况,因此,在每次遇到一个前缀起点的合法串后都进行比较记录是否是最大合法串。
这样缺少考虑了前缀不匹配的情况。将整个串反转、颠倒一下,重复上面的计算。
得到两个数的大的那一个即时最大值。

3. 代码

class Solution {
public:
    // 进栈出栈验证, 出现不匹配时清空堆栈
    // 由于只有一种括号类型, 因此只需要记录在栈中的左括号的数量即可
    // 对遇到的所有有效情况记录最大值
    // 由于最后可能遇到一个末端无效的串
    //   但前面有效部分可能是最大的,
    //   因此进行一次反转后,再次计算,求最大值
    int longestValidParentheses(string s) {
        int c1 = f(s);
        //cout << s << c1 << endl;
        // 对于前缀无效的通过反转同等计算
        reverse(s.begin(), s.end());
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == '(') {
                s[i] = ')';
            } else {
                s[i] = '(';
            }
        }
        int c2 = f(s);
        //cout << s << c2 << endl;
        return max(c1, c2);
    }
    int f(string& s) {
        int left_cnt = 0;
        int max = 0;
        int cur = 0;
        for (int i = 0; i < s.length(); i++) {
            char co = s[i];
            if (co == ')') {
                if (left_cnt == 0) {
                    if (max < cur) {
                        max = cur;
                    }
                    cur = 0;
                    continue;
                } else {
                    left_cnt--;
                    cur++;
                    // 匹配到一个临时的有效串, 后续有可能有更长的, 不清零继续尝试
                    // 也有可能找到的最长的是一个后缀无效的
                    if (left_cnt == 0 && cur > max) {
                        max = cur;
                    }
                }
            } else {
                left_cnt++;
                cur++;
            }
        }
        return max;
    }
};

knzeus
72 声望28 粉丝

行万里路,读万卷书