32. 最长有效括号

题目描述

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

方法1

思路

用栈解决这个问题:匹配 抵消

这题关键的一点是栈中保存index下标位置,而不是保存字符。将index保存在栈中,然后匹配的index会出栈,全部的抵消掉,剩下的就是不能匹配的index。两个不能匹配的下标index中间的都是能够匹配的,其中有两个细节需要注意,就是两边的边界:左边界是-1,右边界是s.size(),两个下标i,j之间的元素个数为:i+k+1=j,k=j-i-1.

代码实现

class Solution {
public:
    int longestValidParentheses(string s) {

    	int n = s.size();
        if(n==0 || n==1)
            return 0;
        stack<int> stk;
        for(int i = 0;i < n;i++)//遍历一个个元素,流式处理
        {  

           if(s[i]==')' && !stk.empty() && s[stk.top()] == '(')
                stk.pop();
            else
                stk.push(i);
        }
        if(stk.empty()) 
        	return n;
        int ret = 0;
        int right = n;
        while(!stk.empty())
        {
            int left = stk.top();
            stk.pop();
            ret = max(ret,right-left-1);
            right = left;
        }
        ret = max(ret,right);
        return ret;
    }
};

方法2

思路

和上面的用栈的思路一样,但是实现不同,我们边做边更新,只需要一次遍历

代码实现

class Solution {
public:
    int longestValidParentheses(string s) {

        int n = s.size();
        if(n==0 || n==1)
            return 0;       
        int ret = 0;
        stack<int> stk;
        //流式处理,其实这里用栈模拟了动态规划中间操作的流程
        //遇到能和当前的")"匹配的情况时,我们计算得到的长度不是
        //局部的这个匹配串的长度,而是整体的字符串中以这个")"
        //结尾的最长的包含有效括号的子串的长度
        for(int i = 0; i < n; ++i)
        {
            if(s[i]==')' && !stk.empty() && s[stk.top()]=='(')
            {
            	stk.pop();//向左尽量扩展
                if(!stk.empty())
                	ret = max(ret, i-stk.top());
                else                          
                	ret = max(ret, i + 1);
            }                           
            else
            	stk.push(i);
        }        
        return ret;
    }
};

方法3

思路

动态规划:
dp[i]:
由当前的')'与之对应匹配的'('(假设它的下标为index)之间形成的局部长度+dpindex-1](向左能扩展的最大长度)

代码实现

class Solution {
public:
	int longestValidParentheses(string s) {

        int n = s.size();
        if(n==0 || n==1)
        	return 0;
        vector<int> dp(n, 0);//dp[i]表示以当前位置为终点的最长长度,则只能在')'处更新
        int ret = 0;
        for(int i = 1; i < n; i++)//动态规划,流式处理 
        {
            if(s[i] == '(')
            	dp[i] = 0;
            else
            {    
                int index = i-dp[i-1]-1;
                if(index >= 0 && s[index]=='(')
                {
                    dp[i] = dp[i-1] + 2;
                    if(index-1 >= 0) 
                    	dp[i] += dp[index-1];
                }
            }
            ret = max(ret, dp[i]);
        }

        return ret;
    } 
};

posted on 2021-07-20 21:10  朴素贝叶斯  阅读(32)  评论(0编辑  收藏  举报

导航