leetcode 32 最长的有效括号

Posted by kele on April 6, 2019

Leetcode 32 最长的有效括号

开胃菜 Leetcode 20 有效括号

给定一个字符串,判断括号等符号个数能否匹配正确
很明显,需要使用堆栈,流程:

  1. 遇到左侧符号时,将其推入到栈中
  2. 遇到右侧符号时,判断栈是否为空
  3. 若栈为空,直接 return false ,因为这时候需要一个左括号弹出栈,而我们是空栈,所以不匹配
  4. 若栈不为空,判断栈顶元素是否与当前符号相匹配,若匹配,则弹出,若不匹配,则 return false
  5. 返回第一步
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 的立方

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。利用堆栈保存下上个有效匹配括号的索引。

  1. 逐个遍历字符串
  2. 假如字符串是 ‘(‘ ,将其 index 压入栈中
  3. 假如是 ‘)’ ,出栈
  4. 判断此时栈是否为空,若为空,则表示前面的符号都已经匹配,当前符号并不会匹配前面,是新的开始,所以将当前 index 压入栈中
  5. 若栈不为空,则表示连续匹配,此时更新 maxlength=max(maxlength,i-ss.top()), ss.top()表示的是本次最长匹配的开头位置
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());
                }
            }
        }
    }
};