[LeetCode]—Longest Valid Parentheses 最长括号匹配

本文详细介绍了如何通过栈和动态规划解决寻找字符串中最长有效括号子串的问题,并提供了两种算法的实现代码。通过实例分析和代码解释,深入理解长有效括号子串的计算方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Longest Valid Parentheses

 

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

分析:

       由于是计算长度,直接单纯栈并不能解决问题。但是如果可以用栈记录下标,那么还是可以求解的。

       方法一:用栈存储“)”的下标,当遇到“(”的时候进行分析,时间复杂度O(N):

      从前之后,遍历string。遇到“(”入栈,遇到“)”讨论。其中last记录最后不匹配的下标,初始化为-1。

    1、此时栈为空,那说明“)”不能匹配。用last记录下其坐标。

    2、当栈不为空时,匹配上,出栈后:(1)此时栈依然不空,那么当前可匹配的括号为i-st.top();

                                                                      (2)此时栈空了,说明之前全部匹配上。那么最后一个没匹配的存在last中。i-last就是之前匹配上的括号的数目。

 

 代码出自:https://gitcafe.com/soulmachine/LeetCode

class Solution{
public:
       int longestValidParentheses(string s){
        stack<int>  st;  //存的是‘(’的下标
        int max_len=0,last=-1;  //last 存的是最后一次没匹配的')'
        
        for(int i=0;i<s.size();i++){
           if(s[i]=='('){
               st.push(i);
            }else{  //重点考察“)”,以找到以第一个未被匹配的“(”为参考。
              if(st.empty()){
                 last=i;
                }
               else {
                   st.pop();
                   if(st.empty())
                        max_len=max(max_len,i-last);
                   else{
                     max_len=max(max_len,i-st.top());
                   }
                }
            }
        }
        return max_len;

        }

};

方法二:用一维动态规划逆向求解。dp[i]表示从s[i]到s[s.length - 1]包含s[i]的最长的有效匹配括号子串长度。

方法出自:http://blog.youkuaiyun.com/yapian8/article/details/28239003


class Solution {
public:
    int longestValidParentheses(string s) {
       int n=s.length();
       if(n<2)return 0;
       int *dp=new int[n];
       int max_len=0;
        for(int i=0;i<n;i++)
            dp[i]=0;
        for(int i=n-2;i>=0;i--){
          if(s[i]=='('){   //只处理“(”,右括号设为0
             int j=i+1+dp[i+1];  
             if(s[j]==')'&& j<n){  
                dp[i]=dp[i+1]+2;
              if(j+1<n)
                    dp[i]+=dp[j+1];
                } 
            }
             max_len=max(max_len,dp[i]);
        }
         return max_len;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值