Longest Valid Parentheses[leetcode] 的三种解法

本文介绍了三种解决最长有效括号问题的方法:使用栈记录非法括号位置、一维动态规划以及改进的栈法。详细阐述了每种方法的实现思路及代码示例。

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

这一题有三种解法

第一种解法利用栈将不合法的括号的下标留在栈里----还记得怎么利用栈判断一组括号是否合法吗;)

也是我第一次做的时候想到的方法,这次重新改了下代码,让它看起来更加优雅

int longestValidParentheses(string s) {
		int length = s.length();
		if (length < 2)
			return 0;
		vector<int> indexStack;
		int maxLength = 0;
		for (int index = 0; index < length; index++)
		{
		    if (s[index] == ')' && !indexStack.empty() && s[indexStack.back()] == '(')
			{
				indexStack.pop_back();
				if (!indexStack.empty()) maxLength = max(maxLength, index - indexStack.back());
				else maxLength = max(maxLength, index + 1);
				continue;
			}
			indexStack.push_back(index);
		}
		
		return maxLength;
	}


第二种解法是一维DP,https://oj.leetcode.com/discuss/8092/my-dp-o-n-solution-without-using-stack 有详细的介绍。dp[i]是以i为尾巴的最长的括号对的长度

有以下两种情况

s[i] == '('dp[i] = 0, 因为以'('结尾的字符串不是合法的括号对

s[i] == ')'

s[i-1] == '('dp[i] = dp[i-2] + 2 ==>()()

s[i-1] == ')' && s[i-dp[i-1]-1] == '('dp[i] = dp[i-1] + 2 + dp[i-dp[i-1]-2] ==>()(())

int longestValidParentheses(string s) {
        int n = s.size();
        if (n <= 1) return 0;
        
        int* dp = new int[n];
        memset(dp, 0, sizeof (int) * n);
        int maxl = 0;

        for (int i = 1; i < n; i++)
        {
            if (s[i] == ')')
            {
                if (s[i-1] == '(')
                    dp[i] = i - 2 > 0 ? 2 + dp[i - 2] : 2;
                else if (s[i-1] == ')' && i - dp[i - 1] - 1 >= 0 && s[i - dp[i - 1] - 1] == '(')
                    dp[i] = 2 + dp[i - 1] + (i - dp[i - 1] - 2 > 0 ? dp[i - dp[i - 1] - 2] : 0);
                maxl = max(maxl, dp[i]);
            }
        }
        delete[] dp;
        return maxl;
    }



第三种方法,利用栈,栈中存放到当前括号为止的长度。

左括号放入-1,遇到右括号则在栈中寻找-1,并加上遇见的所有>0的数

int longestValidParentheses(string s) {
        vector<int> lstack;
        int maxl = 0, index = 0;
        while (index < s.size())
        {
            if (s[index++] == '(')//(则在栈中加-1
                lstack.push_back(-1);
            else
            {
                int curl = 0;
                while (!lstack.empty())//在栈中寻找第一个为-1的值--匹配)
                {
                    if (lstack.back() == -1)
                    {
                        curl += 2;
                        lstack.pop_back();
                        //加上之前的:()()这种情况
                        while (!lstack.empty() && lstack.back() > 0)
                        {
                            curl += lstack.back();
                            lstack.pop_back();
                        }
                        maxl = max(maxl, curl);
                        lstack.push_back(curl);
                        break;
                    }
                    //加上里面的:(())这种情况
                    curl += lstack.back();
                    lstack.pop_back();
                }
            }
        }
        return maxl;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值