问题描述:
给一个只包含 '('
和 ')'
的字符串,找出最长的有效(正确关闭)括号子串的长度。
对于 "(()"
,最长有效括号子串为 "()"
,它的长度是 2。
另一个例子 ")()())"
,最长有效括号子串为 "()()"
,它的长度是 4。
思路很简单:栈回溯,分为情况讨论
对于当前字符,如果是"(",直接压入栈中。如果是")",要分以下几种情况讨论:
(1)如果当前栈为空,说明不存在与当前右括号配对的左括号,直接continue.
(2)如果当前栈大小为1:
a.如果栈顶元素是"(",则找到一个有效的括号序列,弹出栈顶元素,并压入这个序列的长度2;
b.如果栈顶元素是数字,说明不存在与当前右括号配对的左括号,且由于插入了一个右括号,之前得到的括号序列无法更长,需要弹出栈顶元素。
(3)如果当前栈的大小大于等于2:
弹出栈顶元素
a.如果是"(",则找到一个为2的有效序列,再检查栈顶元素,如果是数字,说明可以与前面找到的括号序列合并为一个更大的序列,与其相加后压入栈,否则直接将2压入栈;
b.如果是数字,由于当前的栈大小大于等于2,则下一个栈的元素一定是“(”,弹出后压入合并后的序列长度,压之前再检查,如果栈顶元素还是为数字,则再合并,再压入。
代码如下:
int longestValidParentheses(string s) { int max = 0,len = s.size(); stack<int> st_aux; for(int i = 0; i < len; i++){ if(s[i] == '(')st_aux.push(0);//注意这里不能直接push('(');因为‘('ascii码为40,如果刚好累计长度到40,则使判据混乱,这里卡了好久啊 if(s[i] == ')'){ if(st_aux.empty())continue; else if(st_aux.size() == 1){ if(st_aux.top() == 0){ st_aux.pop(); st_aux.push(2); max = 2 < max?2:max; } else st_aux.pop(); } else { int temp = 0; if(st_aux.top() == 0){ st_aux.pop(); temp = 2; st_aux.push(temp); } else{ temp = st_aux.top(); st_aux.pop(); st_aux.pop(); temp += 2; st_aux.push(temp); } temp = 0; while(!st_aux.empty()&&st_aux.top() != 0){ temp += st_aux.top(); st_aux.pop(); } st_aux.push(temp); if(temp > max)max = temp; } } } return max; }
注意这里不能直接push('(');因为‘('ascii码为40,如果刚好累计长度到40,则使判据混乱,这里卡了好久啊。方法二:动态规划,请看链接 https://blog.csdn.net/u010232171/article/details/44728535