Leetcode 32 最长的有效括号
开胃菜 Leetcode 20 有效括号
给定一个字符串,判断括号等符号个数能否匹配正确
很明显,需要使用堆栈,流程: 1. 遇到左侧符号时,将其推入到栈中 2. 遇到右侧符号时,判断栈是否为空 3. 若栈为空,直接 return false ,因为这时候需要一个左括号弹出栈,而我们是空栈,所以不匹配 4. 若栈不为空,判断栈顶元素是否与当前符号相匹配,若匹配,则弹出,若不匹配,则 return false 5. 返回第一步
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public: bool isValid(string s) { stack<char> ss; for(int i=0;i<s.length();i++){ if(s[i]=='('||s[i]=='{'||s[i]=='[') ss.push(s[i]); else{ if(ss.empty()) return false; if(s[i]==')'&&ss.top()=='(') { ss.pop(); }else if(s[i]=='}'&&ss.top()=='{') { ss.pop(); }else if(s[i]==']'&&ss.top()=='['){ ss.pop(); }else return false; } } if(ss.empty()) return true; else return false; } };
|
算法复杂度 O(n)
注意: 记得遇到右侧符号的时候,要检查栈是否为空,否则后面会访问空栈
Leetcode 32 最长的有效括号
Hard
brute force 爆破
首先想到的是遍历所有的子字符串,长度从1-n,长度为 1 的有 n 个,长度为 2 的有 n-1 个,....,长度为 n 的只有 1 个,所以子字符串的个数总数为 n*n 个,并且我们检查一个子字符串是否为有效的匹配,复杂度是 n,因此最后的复杂度是 n 的立方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution { public: bool isvalid(string s){ stack<char> ss; for(int i=0;i<s.length();i++){ if(s[i]=='('){ ss.push(s[i]); }else if(!ss.empty()){ ss.pop(); }else{ return false; } } return ss.empty(); } int longestValidParentheses(string s) { int cnt=0; for(int i=0;i<s.length();i++){ for(int j=i+2;j<=s.length();j+=2){ if(isvalid(s.substr(i,j-i))){ cnt=max(j-i,cnt); } } } return cnt; } };
|
提交之后: 超时
利用堆栈
因为本题目中的符号只有 '(' ')',所以我们考虑向堆栈中推入字符串的 index。利用堆栈保存下上个有效匹配括号的索引。
- 逐个遍历字符串
- 假如字符串是 '(' ,将其 index 压入栈中
- 假如是 ')' ,出栈
- 判断此时栈是否为空,若为空,则表示前面的符号都已经匹配,当前符号并不会匹配前面,是新的开始,所以将当前 index 压入栈中
- 若栈不为空,则表示连续匹配,此时更新 maxlength=max(maxlength,i-ss.top()), ss.top()表示的是本次最长匹配的开头位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public: int longestValidParentheses(string s) { int maxlength=0; stack<int> ss; ss.push(-1); for(int i=0;i<ss.length();i++){ if(s[i]=='('){ ss.push(i); }else{ ss.pop(); if(ss.empty()){ ss.push(i); }else{ maxlength=max(maxlength,i-ss.top()); } } } } };
|