[32] Longest Valid Parentheses

来源:互联网 发布:开源crm java 源码 编辑:程序博客网 时间:2024/06/18 10:16

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。

2. 解题思路

想起之前学习编译原理做语言处理时通常使用栈来进行左右括号的匹配,所以对于括号的匹配我最先想到的是使用栈,当遇到左括号时入栈,遇到右括号时出栈,这样匹配一对括号。由于题目中需要计算长度,所以在栈中保存左括号在表达式中所在的位置,并在碰到右括号出栈时将左右括号的位置组成一对< left, right >值,right-left+1即为他们相距的长度。
但由于有可能出现以下情况,以上的处理还不够

( )( )

当括号为这样的情况时,最长长度为4,通过上述入栈方式会有两对值<1,2> <3,4>被保存起来,所以考虑将这样的值进行结合,即第一对的right值+1=第二对的left值时,两对值应该做连接,变为<1,4>。
这样的处理过后只需遍历所有保存下来的位置对,找出最长长度即可。

3. Code

#include<stack>class Solution {public:    // 保存当前满足的左右括号位置,长度=left-right+1    class pos    {    public:        int left;  // 左括号位置        int right;  // 右括号位置        pos(int l, int r)        {            left = l;            right = r;        }    };    int longestValidParentheses(string s) {        vector<pos*> all;  // 保存有效括号位置对        stack<int> parentheses;  // 保存左括号位置        for(int i(0); i < s.length(); ++i)        {            if(s[i] == '(')            {                parentheses.push(i);  // 左括号位置入栈            }            else if(s[i] == ')')            {                // 如果括号栈不为空                if(!parentheses.empty())                  {                    int num(0);                    for(int k(0); k < all.size(); ++k)                    {                        // lr pi                        // 34 56  => 36                        // 对所有满足条件的做连接                        if(all[k]->right+1 == parentheses.top()){                            all[k]->right = i;                            num++;                        }                    }                    // 如果没有能连接的就将当前的存入                    if(num == 0)                    {                        all.push_back(new pos(parentheses.top(), i));                    }                    parentheses.pop();  // 左括号出栈                }            }        }        pos* tmpPos(NULL);        int max(0), tmp(0);        // 一个符合的都没有        if(all.size() == 0)            return 0;        // 遍历所有位置对取最大的作为结果        for(int j(0); j < all.size(); ++j)        {            tmpPos = all[j];            tmp = tmpPos->right - tmpPos->left + 1;            if(tmp > max)            {                max = tmp;            }        }        return max;    }};
0 0