[leetcode]Longest Valid Parentheses

来源:互联网 发布:directx游戏编程 编辑:程序博客网 时间:2024/06/05 06:45


题目: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.

题目解析:括号匹配的问题在编程中由来已久。刚开始学习stack的时候,就讲到了如何通过栈来检验一个括号的序列是否合法。这个题目是在原来的基础上进行变形,需要额外的一些考虑。

下面就从最简单的开始思考吧。

最naive的想法就是对所有substring进行检查,从而找到最长的那个子串。算法的时间复杂度是o(n*n)。空间复杂度为o(1)。即将每个左括号当成1,每个右括号当成-1,利用dp中的想法,从左往右,从上往下,进行遍历。递归的公式如下:

d[i][j] =

d[i][j - 1] + 1,           if s[j] == '(', d[i][j - 1] >= 0 

d[i][j - 1] - 1,         

1                              if s[j] == '(', d[i][j - 1]  < 0

其中是不需要存储矩阵的。在循环的过程中可以直接进行最长子串长度的求取,每次只存储当前位置下的值,便于下一个值的计算。

这样的一个算法在时间复杂度上不能满足题目的要求。

那么我们来看看能否在O(n)的时间能完成这样的计算呢?

采用栈的方式来进行统计存在的最大的一个问题是面对如下的串:

()(()

如果能很好的解决这样的问题,就能在o(n)时间内完成算法。最直接的想法是记录下所有匹配的括号在串s中的下标。当然,要找到最长的substring,就需要对这些匹配对进行合并。当然,这种合并是可以边处理,边进行的。主要基于一个很简单的事实:假设当前的匹配对为current(i,j)。在当前匹配对之前已经匹配的那些括号对,要么是在pos i 和 pos j 之间,要么就相邻的匹配对。这样,每次得到一个匹配对时,就考虑和前面的进行合并。这样,当最终遍历玩所有的字符时,栈中的所有匹配对之间都是分割的匹配。只需要找到最长的那个就行了。

下面给出代码实现:

class Solution {public:int static longestValidParentheses(string s) {stack<pair<char,int>> stk;stack<pair<int, int>> record;int len = s.length();for (int i = 0; i < len; i++){if (s.c_str()[i] == '(')stk.push(make_pair('(', i));else{if (!stk.empty()){pair<char, int> st = stk.top();stk.pop();if (!record.empty()){pair<int, int> rt = record.top();if (rt.first > st.second && rt.second < i){record.pop();rt = make_pair(st.second, i);if (!record.empty()){pair<int, int>  rt1 = record.top();if (rt1.second + 1 == rt.first){record.pop();rt = make_pair(rt1.first, rt.second);}}record.push(rt);}else if(rt.second + 1 == st.second){record.pop();record.push(make_pair(rt.first, i));}else{record.push(make_pair(st.second, i));}}elserecord.push(make_pair(st.second, i));}}}int max = 0;while (!record.empty()){pair<int, int> p = record.top();if (p.second - p.first + 1 > max)max = p.second - p.first + 1;record.pop();}return max;}};


0 0
原创粉丝点击