Longest Valid Parentheses

来源:互联网 发布:网络大电影有效转化率 编辑:程序博客网 时间:2024/05/18 09:12

题目

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.

思路一

(1)先将 string 转化为更容易操作的数组,'(' 是1,  ')' 是-1;

(2)用 left 和 right 指针记录最大长度的子串左右边界,并用sum记录当前的和:

          如果sum==0,表示已经匹配,更新最大值 max = max>(right+1-left)?max:(right+1-left) ;

          如果sum>0,表示未匹配,需要右移 right ;

          如果sum<0,表示匹配过当,需要将左边界 left 更新至 right+1 的位置;

(3)当然会出现结束时sum>0的情况,例如 ( ( ( ) ( ) ) ,遍历结束时sum=1,left=0,right=7,始终都未更新max。

          这是就需要一个翻转操作,即将结束时 left~rght-1的字符串翻转(位置和值同时翻转),再接着遍历left~rght-1,更新max。

(4)具体实现时,只需要两遍遍历即可:从前到后 maxLR ,从后到前 maxRL ,再取两者最大值,即为结果。

 

class Solution {public:    int longestValidParentheses(string s) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        int len = s.length();        if(len<2)  return 0;        vector<int> value(len,0);        for(int i=0;i<len;i++) {            if(s[i]=='(') value[i]=1;            if(s[i]==')') value[i]=-1;        }               int maxLR = maxlenLR(value);         int maxRL = maxlenRL(value);        return max(maxLR,maxRL);            }        int maxlenLR(vector<int> &value) {        int sum=0;        int max = 0;        int left=0,right=0;        while(right<value.size()) {            sum+=value[right];            if(sum<0) {                if(right-left>max)                    max=right-left;                left=right+1;                right=left;                sum=0;                continue;            }            if(sum==0) {                max = max>(right+1-left)?max:(right+1-left);            }            right++;                    }        if(sum==0){            max = max>(right-left)?max:(right-left);        }           return max;              }        int maxlenRL(vector<int> &value) {        int sum=0;        int max = 0;        int left=value.size()-1,right=value.size()-1;        while(left>=0) {            sum+=value[left];            if(sum>0) {                if(right-left>max)                    max=right-left;                right=left-1;                left=right;                sum=0;                continue;            }            if(sum==0) {                max = max>(right+1-left)?max:(right+1-left);            }            left--;                    }        if(sum==0){            max = max>(right-left)?max:(right-left);        }           return max;              }};

时间复杂度是 O(3*N) 的,空间复杂度是O(N) 。

再优化一下代码长度 :时间复杂度为 O(2*N),空间复杂度是O(1)

class Solution {  public:      int longestValidParentheses(string s) {          // Start typing your C/C++ solution below          // DO NOT write int main() function          int len = s.length();          if(len<2)  return 0;                 int maxLR = maxlenLR(s);           int maxRL = maxlenRL(s);          return max(maxLR,maxRL);              }          int value(char c) {        if(c=='(')  return 1;        if(c==')')  return -1;    }          int maxlenLR(string &s) {          int sum=0;          int max = 0;          int left=0,right=0;          while(right<s.size()) {              sum+=value(s[right]);              if(sum<0) {                  max = max>(right-left)?max:(right-left);                 left=right+1;                  sum=0;              }              if(sum==0) {                  max = max>(right+1-left)?max:(right+1-left);              }              right++;                      }          if(sum==0){              max = max>(right-left)?max:(right-left);          }             return max;                }            int maxlenRL(string &s) {          int sum=0;          int max = 0;          int left=s.size()-1,right=s.size()-1;          while(left>=0) {              sum+=value(s[left]);              if(sum>0) {                  max = max>(right-left)?max:(right-left);                 right=left-1;                  sum=0;              }              if(sum==0) {                  max = max>(right+1-left)?max:(right+1-left);              }              left--;                      }          if(sum==0){              max = max>(right-left)?max:(right-left);          }             return max;                }    }; 


思路二

用栈保存 '(' 的位置,如果遇到 ')' :

(1)若栈非空,则表示可以匹配,将 '(' 和 ')' 都置为 'Q' ;

(2)若栈为空,则表示当前的 ')' 不能匹配,则继续往下找;

然后遍历修改之后的 字符串,找到最长的连续 'Q' 序列,即为结果。

class Solution {  public:      int longestValidParentheses(string s) {          // Start typing your C/C++ solution below          // DO NOT write int main() function          int len = s.length();          if(len<2)  return 0;                     stack<int> mystack;        for(int i=0;i<len;i++) {            if(s[i]=='(') {                 mystack.push(i);            }            if(s[i]==')') {                if(!mystack.empty()) {                    s[i]='Q';                    s[mystack.top()]='Q';                    mystack.pop();                                    }            }                }        int cur = 0;        int max = 0;        for(int i=0;i<len;i++) {            if(s[i]=='Q') {                cur++;            } else {                max = max>cur?max:cur;                cur=0;                            }                    }          max = max>cur?max:cur;             return max;                }    }; 

时间复杂度为 O(2*N),空间复杂度是O(N) .