版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MyCodecOdecoDecodE/article/details/78245256
LeetCode题目:32. Longest Valid Parentheses
原题链接:https://leetcode.com/problems/longest-valid-parentheses/description/
解题思路:
运用栈进行()的匹配。每个’)’压入栈的时候,判断栈顶是否有’(‘,存在则抵消。如此反复,最后得到的栈即是无法匹配的字符。如果同时记录这些字符在s中下标,则可以得到所有无法匹配字符的位置。相邻的两个字符即是可匹配的最长字符串。
核心思想:
新建一个栈
将字符串所有字符新加一个标记flag,该标记表示它在s中的下标位置
遍历字符串,判断字符:
如果为’(‘,直接压入。
如果为’)’,判断栈顶:如果为’(‘,将’(‘丢弃,否则压入栈中。
将栈中字符依次取出,判断相邻两位字符的flag差值,如果比当前最大子串长度长,更新当前最大子串。
代码细节:
- 用pair保存字符的标记flag
- 有效字符串长度并不等于差值,而等于差值-1
坑点:
- 可能存在最大有效子串在s开头或者结尾。需要多加一次判断
- 可能会出现没有有效子串的情况
代码:
//#include <stack>
int longestValidParentheses(string s) {
int longestLength = 0; // 储存最长长度
int validStringEnd; // 记录有效字符串的终点,用于遍历栈
stack<pair<char, int>> sta; // 用于匹配()的栈,后一个int值记录该符号在字符串s中的位置
for (int i = 0; i < s.length(); i++) {
// 如果为'(',入栈
if (s[i] == '(') {
pair<char, int> p('(', i);
sta.push(p);
}
// 如果为')'
else {
// 判断栈顶是否为'(',如果是,出栈,同时意为存在一个()匹配
if (!sta.empty() && sta.top().first == '(')
sta.pop();
// 不是,则字符串未匹配,子串匹配结束
else {
pair<char, int> p(')', i);
sta.push(p);
}
}
}
// 最后栈中剩下的就是无法匹配的部分,可以获得这些字符在s中的位置
// 栈底的位置前,栈顶的位置后,按顺序排列
// 两个相邻的位置之间存在一个有效字符串
validStringEnd = s.length();
// 依次遍历这些字符串的长度,得到最大值
while (!sta.empty()) {
pair<char, int> p = sta.top();
sta.pop();
if (validStringEnd - p.second - 1 > longestLength)
longestLength = validStringEnd - p.second - 1;
validStringEnd = p.second;
}
// 开头匹配
if (validStringEnd - 0 > longestLength)
longestLength = validStringEnd - 0;
return longestLength;
}