32. Longest Valid Parentheses

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.

Thoughts:

  1. Use stack to keep track of "non parenthesis" index. After the scan, calculate the largest number of parenthesis characters by calculating gaps between tracked indices.

  2. DP: I construct a array longest[] , for any longest[i], it stores the longest length of valid parentheses which is end at i.If s[i] is '(', set longest[i] to 0,because any string end with '(' cannot be a valid one.Else if s[i] is ')'If s[i-1] is '(', longest[i] = longest[i-2] + 2 Else if s[i-1] is ')'and s[i-longest[i-1]-1] == '(', longest[i] = longest[i-1] + 2 + longest[i-longest[i-1]-2]. For example, input "()(())", at i = 5, longest array is [0,2,0,0,2,0], longest[5] = longest[4] + 2 + longest[1] = 6.jerryrcwong's post

Code

class Solution {
public:
    int longestValidParentheses(string s) {
        int len = s.length(), answer = 0;
        if(len == 0) return answer;
        stack<int> st; 
        for(int i =0 ; i < len; i++){
            if(s[i] == '(') st.push(i);
            else if(!st.empty() && s[st.top()]=='(') {
                st.pop();
            }
            else st.push(i);
        }

        if(st.empty()) return len;

        // find longest index gaps in st
        int end = len, start = 0; // here end = len is because we need to 
        // manually figure out the first case : end - start - 1 = # of complete parentheses characters in between two neighboring indices,
        // so to be consistent initial position end here is one postition 1 over the last element in the element as if there is an "virtual"
        // ')' in the end.

        while(!st.empty()){
            start = st.top(); st.pop();
            answer = max(answer, end - start - 1);
            end = start;
        }
        answer = max(answer, end); // compare the number of parenthesis character skiped till the first index, do not need extra "-1" since 
        // there is no start index any more (or the "virtual" starting index is at -1)
        cout<<end<<endl;
        return answer;
    }
};

Code: DP

Python

Special thanks: LeetCode Discussion Forum for the reference!

Last updated

Was this helpful?