题目

给定一个字符串只包含’(‘和’)’,输出其中最长的括号正确匹配的子序列的长度。

举例

输入 输出
()) 2
)()()) 4
(() 2
(()()()()( 8

以下将介绍三种复杂度为O(n)的算法

算法1

该算法利用了栈来遍历可能的匹配的括号子序列,遍历的同时找出最长的子序列。遍历不会遍历所有的匹配括号子序列,并排的一些括号只有包含最左边括号的子序列被遍历,最长的括号子序列肯定能被遍历。
栈顶记录的是与目前探查的括号序列并列的最左边的括号的前一个字符的位置。
从左向右遍历字符串元素。遇到左括号则将该位置压入栈。如果遇到右括号的话,如果不能与栈顶的左括号匹配,则说明这个右括号是多余的,压入栈。如果遇到右括号能匹配,则找到了一个括号序列。这个时候栈顶元素为与这个右括号匹配的左括号的位置。但注意到可能有多个括号并列的情况,进行一次出栈后栈顶元素就是与目前探查的括号序列并列的最左边的括号的前一个字符的位置。观察到了一个新的括号序列,更新最大长度。

int longestValidParentheses1(std::string s) {std::stack<int> beginOfPossibleParenStack;int result = 0;beginOfPossibleParenStack.push(-1);for (int i = 0; i < s.size(); ++i) {if (s[i] == ')' &&beginOfPossibleParenStack.size() > 1 &&s[beginOfPossibleParenStack.top()] == '('){beginOfPossibleParenStack.pop();result = std::max(result, i - beginOfPossibleParenStack.top());} else {beginOfPossibleParenStack.push(i);}}return result;
}

算法2

算法2使用了动态规划思想。使用一个数组记录以i结尾的最大匹配括号子序列长度。
还是从左向右遍历字符串,同时记录左括号减去右括号的个数,最小为0,借此可以忽略多余的右括号。找到了一个不多余的右括号后,计算以他结尾的括号序列长度,不仅包括这对括号内部的括号,还要加上这对括号前面的与其并列的括号。

int longestValidParentheses2(std::string s) {std::vector<int> lenOfLongestParenEndedAt = std::vector<int>(s.size(), 0);int result = 0;int leftParenthesesCount = 0;for (int i = 0; i < s.size(); ++i) {if (s[i] == '(') {leftParenthesesCount++;} else if (leftParenthesesCount > 0) {leftParenthesesCount--;lenOfLongestParenEndedAt[i] = lenOfLongestParenEndedAt[i - 1] + 2;int beforeCurrentParen = i - lenOfLongestParenEndedAt[i];if (beforeCurrentParen >= 0) {lenOfLongestParenEndedAt[i] += lenOfLongestParenEndedAt[beforeCurrentParen];}result = std::max(result, lenOfLongestParenEndedAt[i]);}}return result;
}

算法3

这个算法不仅时间复杂度为O(n),而且空间复杂度为O(1)。
原字符串中匹配序列左侧要么是空要么是括号不匹配的,右侧也一样。字符串相当于一个已经匹配的括号序列左边和右边加入不匹配的括号序列产生的。
对于一个括号完全匹配的字符串,在从左向右遍历的同时记录左括号和右括号的个数,那么显然遇到左括号个数等于右括号个数的时候则已经遍历的部分是括号完全匹配的,匹配括号序列中左括号数目等于右括号数目,这样就可以知道匹配括号子序列的长度。在这个的基础上,如果在字符串的右边加入一个括号不匹配的序列,则原算法可以继续工作。如果在字符串左侧加入一个右括号比左括号多的序列,则原来的算法无法工作,但是只要发现右括号比左括号多则将已遍历的部分去掉,即将计数清零,算法就可以继续工作。如果在字符串左侧加入一个左括号比右括号多的序列,则原来的算法无法工作。这个时候只要从右向左再进行一遍上述算法,就能正常工作。

int longestValidParentheses3(std::string s) {int leftNum = 0;int rightNum = 0;int result = 0;for (int i = 0; i < s.length(); i++) {if (s[i] == '(') {leftNum++;} else {rightNum++;}if (leftNum == rightNum) {result = std::max(result, 2 * rightNum);} else if (rightNum > leftNum) {leftNum = 0;rightNum = 0;}}leftNum = rightNum = 0;for (int i = s.length() - 1; i >= 0; i--) {if (s[i] == '(') {leftNum++;} else {rightNum++;}if (leftNum == rightNum) {result = std::max(result, 2 * leftNum);} else if (leftNum > rightNum) {leftNum = 0;rightNum = 0;}}return result;
}

最长匹配括号子序列问题相关推荐

  1. 第32题 最长匹配括号

    题目: 找出字符串中最长匹配括号的长度,如")()())()()(",结果为4 思路: )  (  ) (  )  ) (  ) (  )  ( 0 1 2 3 4 5 6 7 8 ...

  2. 最长合法括号子序列(括号序列+贪心)

    1.题目引入: 一个合法的括号序列满足以下条件: 序列()被认为是合法的. 如果序列X与Y是合法的,则XY也被认为是合法的. 如果序列X是合法的,则(X)也是合法的. 例如,(),()(),(())这 ...

  3. Leetcode 32 最长合法括号子序列

    算法特辑–动态规划 Leetcode 32 最长合法括号子序列 给定只有"(" 和 ")" 的字符串,求出最长的合法括号子序列. 例如:"())&qu ...

  4. 最长有效括号子串长度 c语言,LeetCode: Longest Valid Parentheses (求最长有效匹配括号子串的长度)...

    题目描述: Given a string containing just the characters'(' and')', find the length of the longest valid ...

  5. 【Python】最长括号匹配问题:给定字符串,仅包含左括号‘(’和右括号‘)’,它可能不是括号匹配的,设计算法,找出最长匹配的括号子串

    最长括号匹配 示例: 给定字符串,仅包含左括号'('和右括号')',它可能不是括号匹配的,设计算法,找出最长匹配的括号子串. 算法分析 只有在右括号和左括号发生匹配时,才有可能更新最终解. 计算s[0 ...

  6. [Jobdu] 题目1337:寻找最长合法括号序列

    题目描述: 给你一个长度为N的,由'('和')'组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的含义便是,在这个序列中,所有的左括号都有唯一的右括号匹配:所有的右括号都有唯一的 ...

  7. LeetCode 32最长有效括号(困难)

    维护不易,还请点个赞赞,如果想加入还请关注公众号bigsai回复进群加入打卡. 题目描述 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. 示例 1: 输入: &qu ...

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

    Title 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. 示例 1: 输入: "(()" 输出: 2 解释: 最长有效括号子串为 " ...

  9. LeetCode 32. 最长有效括号(栈DP)

    文章目录 1. 题目信息 2. 栈 解题 3. 动态规划 解题 1. 题目信息 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. 示例 1:输入: "(() ...

最新文章

  1. linux删除指定创建时间文件(文件夹)脚本
  2. java开发的简易学生成绩管理系统
  3. mahout demo——本质上是基于Hadoop的分步式算法实现,比如多节点的数据合并,数据排序,网路通信的效率,节点宕机重算,数据分步式存储...
  4. C++ cin不支持录入空格
  5. Servlet页面间对象传递的方法
  6. 泛型:工作原理及其重要性
  7. 为什么想要去探究Mybatis源码?(1)
  8. 获得 DataSet中的记录总数
  9. 钱大妈数据中台建设最佳实践
  10. 此地址使用了一个通常用于网络浏览以外的端口。出于安全原因,Firefox 取消了该请求。...
  11. 俄罗斯为何把微积分下放到中学讲授?
  12. numpy基础(part14)--积分
  13. linux系统中使用pycharn,在pycharm中使用linux控制台
  14. 小c下载样式插件Xiaocstyle适用于emlog系统
  15. 【英语学习】【Level 08】U01 Let's Read L6 Person of the year
  16. 今晚8点不见不散!余承东Vlog如此夸赞华为Mate30系列新机
  17. python获取sap数据_python 连接 SAP HANA 数据库
  18. 中燃料场报表生成器--出库报表
  19. HTML+CSS登陆界面实例
  20. 如何将HTML与win10桌面壁纸,如何在Windows 10中将页面设置为桌面背景 | MOS86

热门文章

  1. Conversion failed when converting date and/or time from character string.
  2. 教程篇(6.4) 03. 设备注册 ❀ FortiManager ❀ Fortinet 网络安全专家 NSE 5
  3. php制作公司五章,圆形印章和椭圆形印章,正方形印章,圆角正方形印章,圆角框
  4. mysql中文拼音排序
  5. 服务器恢复系统怎么操作,windows2008用装置盘恢复服务器操作体系
  6. LDA的python实现之模型参数训练
  7. 物联网开发笔记(25)- 使用Micropython开发ESP32开发板之控制LCD1602显示屏
  8. 华硕X550LD笔记本安装黑苹果
  9. 零基础学C语言 第3版 pdf
  10. 【翻译】Dremel: Interactive Analysis of WebScale Datasets