最长的括号子串

最长的括号子串

问题描述

给出一个长度为 n 的,仅包含字符 ‘(‘ 和 ‘)’ 的字符串,计算最长的格式正确的括号子串的长度。

示例:

输入:”(())”

输出:4

解析:对于”(())”来说,最长格式正确的子串是”(())”,所以为4。

分析问题

对于括号匹配问题,最直观的想法就是采用栈来求解。所以,我们也可以采用栈来求解这道题。具体来说,我们在遍历给定字符串的过程中,需要始终保证栈底元素为当前已经遍历过的元素中,最后一个没有被匹配的右括号的下标,栈中的其它元素维护左括号的下标。

  1. 如果遇到的是左括号’(’,我们就把它的下标放入栈中;
  2. 如果遇到的是右括号’)’,此时有两种情况;
  3. 如果此时栈为空,说明当前的右括号是没有被匹配的右括号,
  4. 如果此时栈不为空,右括号的下标减去栈顶元素即为「以该右括号为结尾的最长有效括号的长度」,然后用它来更新最大值即可。

这里需要注意一点,因为一开始栈为空,如果此时第一个字符为左括号时,我们会将其对应的下标放入栈中,这样就不满足栈底始终保存的是最后一个没有被匹配的右括号的下标这个条件,为了保证该条件成立,我们在开始时需要往栈中放入一个元素-1。

我们以”())(())”为例,来看一下执行过程。

最长的括号子串

最长的括号子串

最长的括号子串

最长的括号子串

下面我们来看一下代码实现。

class Solution(object):
    def longestValidParentheses(self, s):
        stack=[]
        n=len(s)
        stack.append(-1)
        maxlen=0
        for i in range(0,n):
            #如果是左括号,将其对应的下标加入栈中
            if s[i]=='(':
                stack.append(i)
            else:
                #如果是右括号,栈顶元素pop出去
                stack.pop()
                if not stack:
                    stack.append(i)
                else:
                    maxlen = max(maxlen, i - stack[-1])

        return maxlen

该算法的时间复杂度和空间复杂度都是O(n)。

动态规划解法

对于求最优解问题,我们一般首先需要考虑的就是动态规划的解法。显然,求最长的括号子串是最优解问题,所有我们也可以采用动态规划的思想来求解。

首先我们定义dp[i]表示以下标i字符结尾的最长有效括号的长度,初始时数组dp全为0。对于有效的括号子串来说,显然是以字符’)’结尾的,因此我们可以知道以’(’结尾的子串对应的dp值必然为0,所以我们只需要求解字符’)’在dp数组中对应位置的值即可。

我们从前往后遍历字符串s。

  1. 如果s[i]=’)’且 s[i-1]=’(’,也就是字符串是 “….()….()….”的形式,那么我们可以得出状态转移方程为dp[i] = dp[i-2] + 2。
  2. 如果s[i]=’)’且 s[i-1]=’)’,也就是字符串是”………))…”的形式,此时如果s[i-dp[i-1]-1] = ‘(’,那么 dp[i] = dp[i-1] + 2 + dp[i – dp[i-1] – 2] 解释:如果 s[i-1] 对应的 ‘)’ 是有效子字符串的一部分,我们假设为sub1,那么它的的长度为dp[i-1],如果s[i]对应的’)’是一个更长子字符串的一部分,那么一定有一个对应的’(’与子相匹配,且它的位置在sub1的之前。如果sub1的前面恰好是’(’,即” (sub1) “的形式,那么dp[i]=dp[i-1] + 2 + dp[i-dp[i-1] – 2] ,其中dp[i-dp[i-1] – 2] 表示字符串”(sub1)”前面的有效子串的长度,我们需要加上。

最长的括号子串

最长的括号子串

最长的括号子串

最长的括号子串

下面我们来看一下代码的实现。

class Solution(object):
    def longestValidParentheses(self, s):
        maxlen=0
        n=len(s)
        dp=[0] * n
        for i in range(1,n):
            #如果s[i]==')'并且s[i-1]=='(',那么dp[i] = dp[i-2]+2
            if s[i]==')':
                if s[i-1]=='(':
                    dp[i] = 2 + (dp[i-2] if i>=2 else 0)
                elif i-dp[i-1]-1 >= 0 and s[i-dp[i-1]-1]=='(':
                    dp[i] = dp[i - 1] + 2 + (dp[i - dp[i - 1] - 2] if i-dp[i-1]>=2 else 0)

                maxlen=max(maxlen,dp[i])
        return maxlen

该算法的时间复杂度是O(n),空间复杂度也是O(n)。

Original: https://www.cnblogs.com/cxyxz/p/15563819.html
Author: 算法推荐管
Title: 最长的括号子串

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/715359/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • []总结常见获客渠道

    [原创]总结常见获客渠道 [原创]总结常见获客渠道 1 搜索 百度 搜狗 360 2 媒体 图文 微信公众号 头条 微博 视频 短视频 抖音 快手 长视频 爱奇艺 腾讯视频 直播 …

    技术杂谈 2023年5月30日
    0189
  • 《软技能-代码之外的生存指南》读书笔记

    《软技能-代码之外的生存指南》读书笔记 写在前面 最近项目相对松了一些,想静下心来看一些书,买了些DDD的书,记得这本书也是程序员必读的书之一,就凑单也买了纸质的来看看~ 抄录一些…

    技术杂谈 2023年7月24日
    096
  • golang 笔记

    for循环,一个key在一个map中,则一直迭代 go总是使用值传递,但是有些数据类型是引用类型,比如map, pointer, channel, slice是部分引用类型 在给函…

    技术杂谈 2023年7月11日
    0110
  • Map<String,String>转String后,转回Map

    public static Map<string,string> mapStringToMap(String str){ str=str.substring(1, st…

    技术杂谈 2023年7月24日
    0118
  • jquery 跨域调用wcf 返回json 碰到的一些问题

    走到这里的时候,发现网络上能学习的资源或是比较适合自己项目的文章越来越少了,也在这里停留了比较长的时间 在做跨域的过程中,感觉http://localhost:9090/域与htt…

    技术杂谈 2023年7月11日
    0148
  • 《商业模式新生代》笔记

    一、组织商业模式画布 为便于理解现有的商业模式,你可以问自己这样两个问题。 我们的客户是谁? 客户需要我们完成哪些工作? 商业模式的九大组成模块 客户群体(Customers) 客…

    技术杂谈 2023年5月31日
    0149
  • c#使用selenium过滑动验证码

    滑动验证码如下: 1、vs引入以下三个包(.net core 3.1): 2、c#引用: private void SeleniumVertifyCode(Uri uri) { v…

    技术杂谈 2023年5月30日
    0159
  • CWE4.8:2022年危害最大的25种软件安全问题

    摘要:我们来看下新版的《2022年危害最大的25种安全问题》在安全预防上会给了我们哪些安全提示。 1. CWE 4.8的变化 2022年过了一半了,继《CWE 4.7中的新视图 –…

    技术杂谈 2023年5月31日
    0165
  • SQL45 将titles_test表名修改为titles_2017

    本题链接本题省略表结构。需要用到RENAME TABLE子句,该子句可实现一或多个表名称的修改。子句语法为: RENAME TABLE tbl_name TO new_tbl_na…

    技术杂谈 2023年7月11日
    099
  • 【转】kubevirt在360的探索之路(k8s接管虚拟化)

    原文:https://blog.51cto.com/u_11451275/4140896?b=totalstatistic apiVersion: v1kind: Persiste…

    技术杂谈 2023年5月30日
    0121
  • R语言_格兰因果检验

    当前文件路径 getwd() 设置当前路径,注意转译 setwd(“C://Users//Administrator//Desktop//R_test”) …

    技术杂谈 2023年7月24日
    0113
  • 哪有什么引用传递,所有都是值传递

    经常看到有人说什么值传递、引用传递,其实都是值传递,区别不过是传的值的类型罢了。 传值方式 java传值有且只有一种方式,将参数的”值”复制后传入,这个&#…

    技术杂谈 2023年7月25日
    093
  • DevOps工程师

    DevOps工程师 1. DevOps工程师的任务是什么? 设计、构建、测试和部署可伸缩的分布式系统,实现从开发到部署的自动化 管理代码库(如Git、SVN、BitBucket等)…

    技术杂谈 2023年5月31日
    0115
  • KMP算法学习记录

    Foreword: 初学KMP匹配算法,不得其门,总感觉自己想,想不出来,看书上文字解释晦涩难懂。不能准确的捕捉算法设计时候的灵光和思路 。于是自己试着完成了一遍,现将过程记录下来…

    技术杂谈 2023年6月21日
    0139
  • TOGAF认证课程,作为讲师我有话说

    来IT帮认证的学员越来越多,每一期总有学员问我”周老师,为什么别人是4天,你这边是2天呢?”我想在这里统一说一下我对TOGAF认证课程的思考。 一. 现状 …

    技术杂谈 2023年5月31日
    0123
  • Qt MSVC与MinGW的区别

    Qt 中有两种方式编译,一种是MinGW ,另一种MSVC。 1.MSVC是指微软的VC编译器。2.MinGW是指是Minimalist GNU on Windows的缩写。它是一…

    技术杂谈 2023年5月31日
    0168
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球