前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode题目32:最长的有效括号

LeetCode题目32:最长的有效括号

作者头像
二环宇少
发布2020-08-18 14:21:22
3100
发布2020-08-18 14:21:22
举报
文章被收录于专栏:互联网西门二少

原题描述

+

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:

代码语言:javascript
复制
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"

示例 2:

代码语言:javascript
复制
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

原题链接:https://leetcode-cn.com/problems/longest-valid-parentheses

思路解析

+

用栈的思路我是没想到,但是有个特点你应该能看出来。

宏观上看,给定的任意序列中,可能包含多组有效括号子串。包含在最长的子串里面的子串,一定也是子问题中最长的子串。

所以,最优子结构,重叠子问题,符合动态规划的场景。

具体地推导如下。

我们开辟一个dp数组记录,存储以 结尾的有效子串的最大长度。因为有效的子串,一定是以')'结尾。所以若 第 个字符并非')',那么dp[i]=0。下面进行递推。

  • 当s[i] == ')'且s[i-1]=='('时: 即对应'......()'的结构出现了。我们把'()'前面的最大有效子串考虑进来,那么
  • 当s[i] == ')'且s[i-1] == ')'时:

即对应'........))'的结构,它可能是')))'的结构,也可能是'())'的结构,也可能是'(())'的结构。只有最后一种情况值得我们去计算,因为前两者虽然以')'结尾,但前面没有匹配的'('。

此种情况是s[i-dp[i-1]-1]=='(',画个图就明白了。

这时的dp数组递推也呼之欲出了,下图中a+b+2即dp[i]的值:

a是处于'((....))'整个子串结构之前的部分,长度dp[i-dp[i-1]-2];

b是被s[i]和s[i-dp[i-1]-1]包着的部分,长度dp[i-1];

2是s[i]和s[i-dp[i-1]-1]这一对。

写代码时注意边界条件,以及上述两个场景的生效条件。

复杂度分析

+

  • 时间复杂度:
  • 空间复杂度:

C++参考代码

+

代码语言:javascript
复制
class Solution {
public:
    int longestValidParentheses(string s) {
        std::vector<int> dp(s.size(), 0);
        int max_cnt = 0;

        for (int i = 1; i < s.size(); ++i) {
            if (s[i] == ')') {
                if (s[i - 1] == '(') {
                    dp[i] = (i - 2 >= 0 ? dp[i - 2] : 0) + 2;
                } else if (i - dp[i-1] - 1 >= 0 && s[i - dp[i-1] - 1] == '(') {
                    dp[i] = (i - dp[i-1] - 2 >= 0 ? dp[i - dp[i-1] - 2] : 0) + dp[i - 1] + 2;
                }
            }
        }

        for (int i = 0; i < dp.size(); ++i) {
            max_cnt = max(max_cnt, dp[i]);
        }

        return max_cnt;
    }
};
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 互联网西门二少 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档