最长括号匹配问题
2016-04-30 15:10
323 查看
最长括号匹配:
给定字符串,仅包含左括号'('和右括号')',它可能不是括号匹配的,设计算法找出最长匹配的括号子串,返回该字串的长度。
如:
(() : 2
()() : 4
()(()) : 6
()(())) : 6
(((()())) : 8
1、首先采用栈的存储方式来解决这个问题:
假设起始匹配位置为start = -1,最大匹配长度为MaxLen,考虑第i位字符c:
如果c是左括号,则进行压栈;
如果c为右括号,它一定与栈顶左括号匹配:
(1)如果栈为空,表示没有匹配左括号,start = i,为下一次匹配做准备;
(2)如果栈不空,出栈。再判断栈是否为空,若为空,MaxLen = max(MaxLen,i-start);若不为空, MaxLen = max(MaxLen,i-栈顶元素位置);
程序实现:
2、采用深度deep表达,将空间复杂度由O(n)降低为O(1).
程序实现:
两者比较且运行结果:
转载请注明出处:
C++博客园:godfrey_88
http://www.cnblogs.com/gaobaoru-articles/
给定字符串,仅包含左括号'('和右括号')',它可能不是括号匹配的,设计算法找出最长匹配的括号子串,返回该字串的长度。
如:
(() : 2
()() : 4
()(()) : 6
()(())) : 6
(((()())) : 8
1、首先采用栈的存储方式来解决这个问题:
假设起始匹配位置为start = -1,最大匹配长度为MaxLen,考虑第i位字符c:
如果c是左括号,则进行压栈;
如果c为右括号,它一定与栈顶左括号匹配:
(1)如果栈为空,表示没有匹配左括号,start = i,为下一次匹配做准备;
(2)如果栈不空,出栈。再判断栈是否为空,若为空,MaxLen = max(MaxLen,i-start);若不为空, MaxLen = max(MaxLen,i-栈顶元素位置);
程序实现:
int GetLongestParentheses(const char* p){ int size = (int)strlen(p); stack<int> s; int MaxLen = 0; int start = -1;//左括号的前一个位置 for(int i=0;i<size;i++){ if(p[i]=='('){//左括号压栈 s.push(i); } else{//为右括号的情况 if(s.empty()) start = i; else{ s.pop(); if(s.empty()) MaxLen = max(MaxLen,i-start); else MaxLen = max(MaxLen,i-s.top()); } } } return MaxLen; }
2、采用深度deep表达,将空间复杂度由O(n)降低为O(1).
程序实现:
int GetLongestParentheses1(const char* p){ int size = (int)strlen(p); int MaxLen = 0; int deep = 0;//遇到了多少左括号 int start = -1;//最深第一个左括号的前一个位置 for(int i=0;i<size;i++){ if(p[i]=='(') deep++; else{ deep--; if(deep==0){ MaxLen = max(MaxLen,i-start); }else if(deep<0){ deep = 0; start = i; } } } deep=0;//遇到了多少右括号 start = size;//最深右括号的后一个位置 for(int i=size-1;i>=0;i--){ if(p[i]==')') deep++; else{ deep--; if(deep==0) MaxLen = max(MaxLen,start-i); else if(deep<0){ deep = 0; start = i; } } } return MaxLen; }
两者比较且运行结果:
#include <iostream> #include <stack> #include <cstring> using namespace std; int GetLongestParentheses(const char* p){ int size = (int)strlen(p); stack<int> s; int MaxLen = 0; int start = -1;//左括号的前一个位置 for(int i=0;i<size;i++){ if(p[i]=='('){//左括号压栈 s.push(i); } else{//为右括号的情况 if(s.empty()) start = i; else{ s.pop(); if(s.empty()) MaxLen = max(MaxLen,i-start); else MaxLen = max(MaxLen,i-s.top()); } } } return MaxLen; } int GetLongestParentheses1(const char* p){ int size = (int)strlen(p); int MaxLen = 0; int deep = 0;//遇到了多少左括号 int start = -1;//最深第一个左括号的前一个位置 for(int i=0;i<size;i++){ if(p[i]=='(') deep++; else{ deep--; if(deep==0){ MaxLen = max(MaxLen,i-start); }else if(deep<0){ deep = 0; start = i; } } } deep=0;//遇到了多少右括号 start = size;//最深右括号的后一个位置 for(int i=size-1;i>=0;i--){ if(p[i]==')') deep++; else{ deep--; if(deep==0) MaxLen = max(MaxLen,start-i); else if(deep<0){ deep = 0; start = i; } } } return MaxLen; } int main() { char str1[] = "(()"; char str2[] = "()()"; char str3[] = "()(())"; char str4[] = "()(()))"; char str5[] = "(((()()))"; cout<<GetLongestParentheses(str1)<<endl; cout<<GetLongestParentheses(str2)<<endl; cout<<GetLongestParentheses(str3)<<endl; cout<<GetLongestParentheses(str4)<<endl; cout<<GetLongestParentheses(str5)<<endl; cout<<"----------------deep O(1)--------------------"<<endl; cout<<GetLongestParentheses1(str1)<<endl; cout<<GetLongestParentheses1(str2)<<endl; cout<<GetLongestParentheses1(str3)<<endl; cout<<GetLongestParentheses1(str4)<<endl; cout<<GetLongestParentheses1(str5)<<endl; return 0; }
转载请注明出处:
C++博客园:godfrey_88
http://www.cnblogs.com/gaobaoru-articles/
相关文章推荐
- 区域赛之位运算
- 详解RocketMQ中的consumer
- maven插件
- 详解RocketMQ中的Producer
- allegro Disable custom colors is enabled
- 背包系列第六篇----完全背包(求解最大价值的个数)
- RocketMq相关介绍
- ARP协议
- 复制指定目录下的指定文件,并修改后缀名
- Windbg、dump分析类资源链接
- 有一个文本文件中存储了几个名称,写一个程序实现随机获取一个人的名字(抽奖)
- test
- 负载均衡算法
- HNOI2016 大数(number)<莫队>
- opencv的CV_EXPORT
- hrbust/哈理工oj 1877 区间【水题】
- 文科状元转CS
- 数据结构相同情况下数据表之间数据的快速"copy"
- maven学习系列3----仓库
- Java注解(二) 系统注解