lecode-32 最长有效括号-动态规划

lecode-32 最长有效括号-动态规划

书接上回,前面我们用了一种暴力解法,最后时间复杂度为O(n2),这次我们使用动态规划和栈的思路来得出一种更为简便高效的算法。为了防止有些朋友没看过上一篇,我再贴一遍题目。
在这里插入图片描述

对于栈的操作如下:

  • 遇到(进行压栈操作
  • 遇到)进行出栈操作

我们使用dp[i]表示以s[i]结尾的最长有效子串,如果s[i]=(那么dp[i]等于0;

那么如果s[i]=)呢,这时候进行的是出栈操作,出栈意味着这里至少有一对括号,那么s[i]前面是什么情况呢,有两种情况:

  • 这对括号中还有其他括号,比如:(()),那么对于最后一个右括号出栈的时候最长子串sub_dp=dp[i-1] +2
  • 这对括号中没有其他括号,比如:(),这里其实可以直接等于2,为了统一公式,最长子串sub_dp=dp[i-1]+2,因为dp[i-1]也就是左括号的值恒为0

这样我们就完成了一个局部子串的长度计算,那么这个子串前面是什么情况,会不会也有连续的有效括号,这里我以中划线区分前后,比如:

  • ()|()
  • ()|(())

因为我们已经知道了后面这一块子串的有效字符长度,那么只需要偏移回去加上中划线前面部分的dp即可,公式为:dp[i] = sub_dp + dp[i - sub_dp],由此我们已经推导出了动态规划的状态转移公式,可以写代码啦。这里在总结一下:

在这里插入图片描述

代码实现如下:

#include<stdio.h>
#include<string.h>

int longestValidParentheses(char* s) {
	int len = strlen(s);
	int i = 0, count = 0;
	int dp[100];
	int sub_dp = 0;
	int max_dp = 0;
	memset(dp, sizeof(dp), 0);
	for (i = 0; i < len; i++)
	{
		if (*(s+i) == '(')
		{
			dp[i] = 0;
			count++;
		}else
		{
			if (count==0)
			{
				dp[i] = 0;
			}else
			{
				count --;
				dp[i] = dp[i-1] + 2;
				if ((i - dp[i]) >= 0)
					dp[i] = dp[i] + dp[i - dp[i]];
			}
		}
		if (dp[i] > max_dp)
			max_dp = dp[i];
	}
	return max_dp;
}
int main(){
    char s[] = ")()()(((())())(";
	printf("result len %d\n", longestValidParentheses(s));
    return 0;
}

lecode通过截图,这次时间复杂度变成了O(n)

在这里插入图片描述

``

lecode通过截图,这次时间复杂度变成了O(n)

在这里插入图片描述

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值