【LeetCode】解题32:Longest Valid Parentheses(多解法:栈+动态规划+计数器)

【信息科学与工程学】【数据科学】数据科学领域 第六篇 算法设计 07 堆、栈、表、矩阵、集合、队列、数组、字符串、树、图、动态规划、结构体、元组的算法01 当前段必须包含所有字符的最后出现位置。1. 字符串分割成最多片段2. 基因序列功能域划分3. 文本段落划分4. 音频声道分离5. 图像色彩分区6. 社交网络社群划分7. 蛋白质结构域8. 音乐乐章分段9. 代码模块划分10. 章节划分特征:一次扫描,贪心确定边界。 阅读详情

LeetCode解题 32:Longest Valid Parentheses(多解法:栈+动态规划+计数器)

Problem 32: Longest Valid Parentheses [Hard]

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

Example 1:

Input: “(()”
Output: 2
Explanation: The longest valid parentheses substring is “()”

Example 2:

Input: “)()())”
Output: 4
Explanation: The longest valid parentheses substring is “()()”

来源:LeetCode

解题思路

1. 栈

维护一个栈,起始压入-1,然后不停压入'('和')'的下标。当')'遇到前面是'('时就消去,并计算有效长度;当')'前面没有'('的时候,说明无效,需要清空并将')'的下标压入最底层,用于之后计算有效长度。

具体思路:

  • 创建栈sk,初始化压入-1。

  • 遍历字符串s,遇到'('时直接压入,遇到'('时需要分情况讨论:
    i. 如果栈顶是'(',将其pop()后计算当前有效长度并更新maxLen:
    m a x L e n = max ⁡ { m a x L e n , i − s k . p e e k ( ) } maxLen = \max\{maxLen, i - sk.peek()\} maxLen=max{maxLen,i−sk.peek()}
    其中,i是当前遍历至的下标,sk.peek()是栈中消去的'('的前一个位置的下标。

    ii. 如果栈顶不是'(',那么一定是-1或者')',并且栈中一定只剩下了一个元素(因为之前所有的')'都会被消去,只剩下一个用于计算有效长度)。此时需要将之前剩余的元素pop(),并将当前的')'下标压入栈,用于后续计算长度。

时间复杂度为 O ( n ) O(n) O(n),空间复杂度最坏情况下为 O ( n ) O(n) O(n)。

运行结果:
在这里插入图片描述

2. 动态规划

使用动态规划思想。维护数组valLen[N],valLen[i]代表以字符串中s[i]结尾的最大有效长度。当s[i] = '('时,valLen[i]一定为零;当s[i] = ')'时,需要同时考虑s[i-1]。

遍历s,valLen[i]根据s[i]和s[i-1]的情况可以由valLen[i-1]、valLen[i-2]、valLen[i-valLen[i-1]-2]等前项转换而来,具体转换公式为:

  1. 当s[i] = '(' 时, v a l L e n [ i ] = 0 valLen[i] = 0 valLen[i]=0。

  2. 当s[i] = ')'时,需要考虑前一个字符,即s[i-1]。

    2.1 若s[i-1] = '(',也就是字符串为###()$,则有效长度应为以s[i-2]结尾的最大有效长度再加2,转换公式为:
    v a l L e n [ i ] = v a l L e n [ i − 2 ] valLen[i] = valLen[i-2] valLen[i]=valLen[i−2]
    2.2 若s[i-1] = ')',也就是字符串为###)),则应该往前推valLen[i-1]个位置,看i-valLen[i-1]-1位置的字符是不是'(',也就是看##x...))中x位置,其中...)的长度就是valLen[i-1],是一个有效字符串。

    如果x = ')',也就不能与s[i]的')'匹配上,则 v a l L e n [ i ] = 0 valLen[i] = 0 valLen[i]=0。

    如果x = '(',则字符串为##(...)),其中...)的长度为valLen[i-1],还要加上新匹配上的两个括号,同时还要看x的前一个字符的最大有效长度(前一个字符为i - valLen[i-1] - 2),因此转换公式为:
    v a l L e n [ i ] = v a l L e n [ i − 1 ] + 2 + v a l L e n [ i − v a l L e n [ i − 1 ] − 2 ] valLen[i] = valLen[i-1] + 2 + valLen[i-valLen[i-1]-2] valLen[i]=valLen[i−1]+2+valLen[i−valLen[i−1]−2]

  3. 最后更新maxLen:
    m a x L e n = max ⁡ { m a x L e n , v a l L e n [ i ] } maxLen = \max\{maxLen, valLen[i]\} maxLen=max{maxLen,valLen[i]}

时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)。

运行结果:
在这里插入图片描述

3. 计数器

创建两个计数器 l e f t left left和 r i g h t right right用于记录左括号和右括号的个数。

第一次从左到右遍历:

  • 遇到'('时, l e f t left left++,遇到)时, r i g h t right right++。
  • 当 l e f t < r i g h t left < right left<right时,说明计数无效, l e f t left left和 r i g h t right right都清零。
  • 当 l e f t = r i g h t left = right left=right时,说明括号可以完全匹配,更新maxLen为:
    m a x L e n = max ⁡ { m a x L e n , l e f t + r i g h t } 。 maxLen = \max\{maxLen, left + right\}。 maxLen=max{maxLen,left+right}。
    如果遍历结束后发现 l e f t > r i g h t left > right left>right说明中间可能有能够匹配上的部分因为左括号较多而无法满足 l e f t = r i g h t left = right left=right,因此需要反向遍历一次。

第二次从右到左遍历:

  • 遇到'('时, l e f t left left++,遇到)时, r i g h t right right++。
  • 当 l e f t > r i g h t left > right left>right时,说明计数无效, l e f t left left和 r i g h t right right都清零。
  • 当 l e f t = r i g h t left = right left=right时,说明括号可以完全匹配,更新maxLen为:
    m a x L e n = max ⁡ { m a x L e n , l e f t + r i g h t } 。 maxLen = \max\{maxLen, left + right\}。 maxLen=max{maxLen,left+right}。

时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)。

运行结果:
在这里插入图片描述

要点:动态规划、栈

Solution (Java)

1. 栈

class Solution {
    public int longestValidParentheses(String s) {
        int N = s.length();
        if(N < 2) return 0;
        int max = 0;
        Stack<Integer> sk = new Stack<Integer>();
        sk.push(-1);
        for(int i = 0; i < N; i++){
            if(s.charAt(i) == '('){
                sk.push(i);
            }
            else{
            	// opt1
                /*if(sk.size() == 1){
                    sk.pop();
                    sk.push(i);
                }
                else{ // sk.peek() = '('
                    sk.pop();
                    max = Math.max(max, i - sk.peek());
                }*/
                // opt2[*]
                sk.pop();
                if(sk.empty()) sk.push(i);
                else{ // sk.pop() = '('
                    max = Math.max(max, i - sk.peek());
                }
            }
        }
        return max;
    }
}

2. 动态规划

class Solution {
    public int longestValidParentheses(String s) {
        int N = s.length();
        if(N < 2) return 0;
        int max = 0;
        int len;
        int[] valLen = new int[N];
        valLen[0] = 0;
        for(int i = 1; i < N; i++){
            if(s.charAt(i) == '(') valLen[i] = 0;
            else{ // s[i] = ')'
                if(s.charAt(i-1) == '('){
                    len = 2;
                    if(i-2 > 0) len += valLen[i-2];
                    valLen[i] = len;
                    max = Math.max(max, len);
                }
                else{
                    len = valLen[i-1];
                    if(i-len-1 < 0 || s.charAt(i-len-1) == ')') len = 0;
                    else{
                        if(i-len-2 < 0) len += 2;
                        else len += valLen[i-len-2] + 2;
                    }
                    valLen[i] = len;
                    max = Math.max(max, len);
                }
            }
        }
        return max;
    }
}

3. 计数器

class Solution {
    public int longestValidParentheses(String s) {
        int N = s.length();
        if(N < 2) return 0;
        int max = 0;
        int left = 0; // num of '('
        int right = 0; // num of ')'
        // from s[0] to s[N-1]
        for(int i = 0; i < N; i++){
            if(s.charAt(i) == '(') left++;
            else right++;
            if(left < right){
                left = 0;
                right = 0;
            }
            else if(left == right){
                max = Math.max(max, left+right);
            }
        }
        if(left < right) return max;
        left = 0;
        right = 0;
        // from s[N-1] to s[0]
        for(int i = N-1; i >= 0; i--){
            if(s.charAt(i) == ')') right++;
            else left++;
            if(left > right){
                left = 0;
                right = 0;
            }
            else if(left == right){
                max = Math.max(max, left+right);
            }
        }
        return max;
    }
}
期末求生指南:手把手教你用F12开发者工具绕过百一测评的切屏检测(JavaScript/jQuery实战) 本文详细介绍了如何利用F12开发者工具绕过百一测评的切屏检测,通过分析JavaScript/jQuery中的blur()和focus()事件监听机制,提供实战技巧动态修改代码。文章涵盖事件监听定位、代码修改方法及应对高级检测机制的策略,适合需要临时解决线上考试限制的学生参考。 阅读详情

相关推荐

关于HC32F460 输出可调占空比PWM波遇到的问题记录

文章目录问题记录一、问题分析二、解决方法总结 问题记录 芯片:HC32F460系列 功能:PWM电机调速 最近产品开发,需要用到HC32的PWM输出来控制电机的转速。参考官方的例程很快就完成了相关的功能,但是,后面在测试,重复开关电机的时候,发现电机的转速时大时小。 一、问题分析 一开始,怀疑是相关寄存器的设置出错导致的问题。因此在设置PWM输出时加上LOG打印,上机测试并没有发现问题。 用示波器抓取波形,这是正常状态下的波形(上电默认配置成5kHz,70%占空比输出) 这是转速较小时的波形输出 .

Top0_0lll的博客 6165

【LeetCode】32. Longest Valid Parentheses【栈&动态规划】

       它的标题基本就是题目了,找出连续的最长有效括号的长度,再看一下原题的两个栗子就更明显了,尤其是第二个栗子中的()()部分,更是此题的一个关键,后面还会经常提起。这道题题意相当简单,思路相当简洁,代码相当简短,但是感觉想起来没有那么简单,做完有一种相当巧妙的感觉,所以分享出来。 Given a string containing just the characters '(' an...

zhaoqinmuxue的博客 312

pi/4QPSK调制解调原理

文章目录1. π/4\pi/4π/4QPSK 信号的调制原理2. 匹配滤波器与成形滤波器 1. π/4\pi/4π/4QPSK 信号的调制原理 减小相位突变量的QPSK由偏置键控QPSK(OK-QPSK)和 π/4\pi/4π/4偏置的QPSK( π/4\pi/4π/4QPSK)。由于 π/4\pi/4π/4QPSK是用差分相位编码产生的(因此也叫做 π/4\pi/4π/4DQPSK),能有效地进行差分解调和鉴频器解调,在一些不易提取相干载波的场合很有用。 在常规的QPSK中,输入数据经过串/并变换后,分成

gemengxia的博客 2万+

leetcode:Longest Valid Parentheses 使用动态规划O(n)思路

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 "()",

通往花开的路上 1031

基于价值的深度强化学习:DQN

本文主要是介绍DQN原理和算法伪代码和代码实现,算法实现包括pytorch版本和stable-baselines3版本

溯源的专栏 1082

sram设计流程+memory compiler整理

→。

qq_50761108的博客 1万+

Longest Valid Parentheses(动态规划)

Longest Valid Parentheses 题目 Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring. Example 1: Input: “(()” Output: 2 Expl...

Vilin的博客 866

083、多帧降噪(MFR)与VST算法:低照度场景下的信噪比提升与鬼影抑制

本文深入探讨了多帧降噪(MFR)和VST算法在低照度场景中的应用与优化。作者从实际项目案例出发,指出单帧降噪的局限性,详细分析了MFR的核心原理与工程实现中的关键环节,包括帧对齐、帧选择、融合策略和鬼影抑制等技术要点。文章特别强调VST变换对噪声均匀化的重要性,并分享了实际开发中的调试经验与参数优化技巧,如"三明治"调试法和性能平衡策略。最后指出,优秀的MFR方案需要在信噪比提升、鬼影抑制和纹理保留之间找到场景化的平衡点,建议开发者通过真实场景测试验证算法效果。全文既有理论分析,又包含丰富的实战经验和技术细

zzfmlxs的博客 121

【LeetCode】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 i

跳出温水的青蛙 2378

OpenSpec 完全指南 config.yaml文件

不管是项目内还是全局存放,自定义工作流都要遵守以下规则,否则会导致OpenSpec无法识别,新手一定要记牢:一个文件夹 = 一个工作流:工作流文件夹的名称,就是中schema字段要填写的名称;每个工作流文件夹必须包含:这是工作流的核心定义文件,没有它,OpenSpec无法识别这个工作流;模板文件统一放templates/目录:如果需要自定义生成文件的模板(比如统一的提案模板、任务模板),就放在工作流文件夹下的templates/里,OpenSpec会自动识别;

h a 6 6 6 c k 为 你解决复杂难题! 1414

【WRF-GHG 教程上】完整教程(2024年更新版)

完整教程(2024年更新版)

WW、forever的博客 1430

Longest Valid Parentheses,二维动态规划、一维动态规划、stack

一、二维动态规划 int longestValidParentheses(string s) {         int len=s.length(),maxLen=0;         bool valid[len][len];  //valid[i][j]表示s[i]...s[j]是否是有效的         memset(valid,false,sizeof(valid));

angelewings的专栏 1362

【软考】系统集成项目管理工程师(一)信息化知识

软考中级——系统集成项目管理工程师备考干货第一章:信息化知识。

商务合作 | 共同学习 | 携手共进 9万+

LeetCode(32):最长有效括号 Longest Valid Parentheses(Java)

2019.10.9 #程序员笔试必备# LeetCode 从零单刷个人笔记整理(持续更新) github:https://github.com/ChopinXBP/LeetCode-Babel 括号题离不开栈,字符串题一般可以走动态规划,这道题主要有三种思路: 1.动态规划 dp[i]代表以第i个括号结尾的最长有效字符串长度。第一个子串必无效,dp[1] = 0。 顺序遍历,如果第i个括号为’(...

NJU_ChopinXBP的博客 427

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

LeetCode 32.Longest Valid Parentheses最长有效括号

题目描述 给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。 示例 1: 输入: “(()” 输出: 2 解释: 最长有效括号子串为 “()” 示例 2: 输入: “)()())” 输出: 4 解释: 最长有效括号子串为 “()()” 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/longest-valid-...

it-hao的博客 296

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

LeetCode String 32 Longest Valid Parentheses

32. Longest Valid Parentheses Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring. Example 1: Input: “(()” Output: 2 Exp...

Yi Jiao's Blog 255

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

LeetCode - 解题笔记 - 32 - Longest Valid Parentheses

Longest Valid Parentheses Solution 1 这一题乍一看和“最长公共子序列”很像,我想了一会动态规划的状态方程,发现能力不行,于是就使用一个比较传统的栈的方式来处理括号,需要额外加一个调整:栈内保存的是对应符号的坐标。整个过程和验证序列有效性的思路类似:匹配则弹出,否则入栈,有效长度就计算弹出后栈顶的索引位置和当前位置的距离,此时二者之间的必然都是匹配完成的(有点贪心的思想)。因此判定逻辑为: 左括号,直接入栈 右括号需要进行检查: 如果当前栈为空,显然当前括号无效,入栈

支锦铭的博客 187

LeetCode:32. Longest Valid Parentheses(最长的有效匹配串)

Given a string containing just the characters'('and')', find the length of the longest valid (well-formed) parentheses substring. 翻译: 在字符串找有效字符串 Example 1: Input: "(()" Output: 2 Explanation: T...

zy345293721的博客 300

LeetCode (32): Longest Valid Parentheses

链接:https://leetcode.com/problems/longest-valid-parentheses/ 【描述】 Given a string containing just the characters'('and')', find the length of the longest valid (well-formed) parentheses su...

weixin_34278190的博客 120

【算法】大厂机考总结和HOT100

【最新最全】华为OD历年机试题集合+OJ刷题网址+刷题经验_华为的外包都要提前刷题 数据库刷题的地址是哪个-优快云博客。

qq_58358642的博客 377

32. Longest Valid Parentheses 动态规划解法

动态规划解法,十分简洁,len[i]定义为以下标i结尾的之前的字符串所能组成的最大有效括号class Solution { public: int longextValidParentheses(string s) { int result=0; vector dp(s.length(),0); for(int i=1;i<s.len

april2009128的博客 742

LeetCode Longest Valid Parentheses 解题报告

分析,求出一串由:‘(’和‘)’组成的字符串中最长有效括号的长度。例如:(()(),结果是4。((()))结果是6。())()()结果是4。

算法的天空 1万+

leecode 32. Longest Valid Parentheses

leecode 32. Longest Valid Parentheses 题目大意 给出一个只含有’(‘和’)’的字符串,求这个字符串里面最长的合理括号组合字符串的长度。 解题思路 一开始觉得会跟判断合法括号字符串一样,用一个stack就能解决,但是发现行不通,因为像”()(()”这种情况,没办法将前后的”()”分开。结果只是154 / 229 test cases passed

默默 368

【Leetcode 32.Longest Valid Parentheses】动态规划

从今天2017.10.15开始记录我的leetcode被虐之旅毫无疑问,这又是一道凭借我一己之力无法解出的题,并且难度分级是hard级别,我也选择这道题作为我学习DP(Dynamic Programming)的开始吧!动态规划的一般是从解决小问题开始,选择自底向上(迭代)或者自顶向下(递归)解决问题 而关键问题就是求出状态转移方程题目描述如下: Given a string contai

Gakkis的专栏 687

动态规划算法06-Longest Valid Parentheses问题

最长合法匹配子串长度(动态规划解法)。 简述 给定一个只包含"(",")"的字符串,是判断一个最长的且能完全匹配的子串的长度。 看到这种最有解问题,本能应该想到是动态规划解题。(且只求最值不求序列的可以递归实现) 这是LeetCode动态规划类别的一道题。 问题描述 给定一个字符串,只包含"(“和”)",规定一个"(“必须匹配一个”)",找一个最长的可以完全匹配的子串长度。 如"((()“...

周先森爱吃素的博客 561

32. 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

且听疯吟的博客 277
上一篇: 【LeetCode】解题10:Regular Expression Matching(动态规划解法)
下一篇: 【LeetCode】解题44:Wildcard Matching(动态规划解法)
Fayedy
博客等级 码龄11年 2粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值