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.

Solution 1: 栈存的是index,不是括号。如果是(,压入index到栈;如果是),若栈顶元素是(,则弹出,否则压入)的index。最后栈中留下的是不配对的index,扫描整个栈,找出这些index间夹着的配对最长长度

    public int longestValidParentheses(String s) {
        if (s == null || s.length() < 2) {
            return 0;
        }
        LinkedList<Integer> stack = new LinkedList<>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);        
            if (c == '(') {
                stack.offerLast(i);   
            } else {
                if (stack.isEmpty() || s.charAt(stack.peekLast()) != '(') {
                    stack.offerLast(i);
                } else {
                    stack.pollLast();
                }
            }

        }
        if (stack.isEmpty()) {
            return s.length();
        }
        int max = 0, cur = s.length();
        while (!stack.isEmpty()) {
            int index = stack.pollLast();
            max = Math.max(cur - index - 1, max);
            cur = index;
        }
        max = Math.max(cur, max);
        return max;
    }

better way:

    public int longestValidParentheses(String s) {
        Stack<Integer> stack = new Stack<Integer>();
        int max=0;
        int left = -1;
        for(int j=0;j<s.length();j++){
            if(s.charAt(j)=='(') stack.push(j);            
            else {
                if (stack.isEmpty()) left=j;
                else{
                    stack.pop();
                    if(stack.isEmpty()) max=Math.max(max,j-left);
                    else max=Math.max(max,j-stack.peek());
                }
            }
        }
        return max;
    }

or:

The idea is simple, we only update the result (max) when we find a "pair".

If we find a pair. We throw this pair away and see how big the gap is between current and previous invalid.

EX: "( )( )" stack: -1, 0,

when we get to index 1 ")", the peek is "(" so we pop it out and see what's before "(".

In this example it's -1. So the gap is "current_index" - (-1) = 2.

The idea only update the result (max) when we find a "pair" and push -1 to stack first covered all edge cases.

    public int longestValidParentheses(String s) {
        LinkedList<Integer> stack = new LinkedList<>();
        int result = 0;
        stack.push(-1);
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ')' && stack.size() > 1 && s.charAt(stack.peek()) == '(') {
                stack.pop();
                result = Math.max(result, i - stack.peek());
            } else {
                stack.push(i);
            }
        }
        return result;
    }

Solution 2: DP

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.

            if(s.length() <= 1) return 0;
            int curMax = 0;
            vector<int> longest(s.size(),0);
            for(int i=1; i < s.length(); i++){
                if(s[i] == ')'){
                    if(s[i-1] == '('){
                        longest[i] = (i-2) >= 0 ? (longest[i-2] + 2) : 2;
                        curMax = max(longest[i],curMax);
                    }
                    else{ // if s[i-1] == ')', combine the previous length.
                        if(i-longest[i-1]-1 >= 0 && s[i-longest[i-1]-1] == '('){
                            longest[i] = longest[i-1] + 2 + ((i-longest[i-1]-2 >= 0)?longest[i-longest[i-1]-2]:0);
                            curMax = max(longest[i],curMax);
                        }
                    }
                }
                //else if s[i] == '(', skip it, because longest[i] must be 0
            }
            return curMax;

results matching ""

    No results matching ""