本文主要是介绍150. 括号画家 栈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
150. 括号画家
达达是一名漫画家,她有一个奇特的爱好,就是在纸上画括号。
这一天,刚刚起床的达达画了一排括号序列,其中包含小括号 ( )
、中括号 [ ]
和大括号 { }
,总长度为 NN。
这排随意绘制的括号序列显得杂乱无章,于是达达定义了什么样的括号序列是美观的:
- 空的括号序列是美观的;
- 若括号序列 AA 是美观的,则括号序列 (A)(A)、[A][A]、{A}{A} 也是美观的;
- 若括号序列 A、BA、B 都是美观的,则括号序列 ABAB 也是美观的。
例如 [(){}]()
是美观的括号序列,而)({)[}](
则不是。
现在达达想在她绘制的括号序列中,找出其中连续的一段,满足这段子序列是美观的,并且长度尽量大。
你能帮帮她吗?
输入格式
输入一行由括号组成的字符串。
输出格式
输出一个整数,表示最长的美观的子段的长度。
数据范围
字符串长度不超过 10^5。
输入样例:
({({(({()}})}{())})})[){{{([)()((()]]}])[{)]}{[}{)
输出样例:
4
思路:由题意得:如果某一段是合法的,那么它们中间的也是合法的。我们用栈来存储左括号,
当遇到左括号时就入栈,遇到右括号时就和栈顶的左括号配对,如果配对成功就将标记左右两端为true;
如果没有配对成功,就清空栈。操作完之后,我们遍历序列,当左端点i满足时,遍历有右端点,当碰到右端点不满足时,就及时更新这一段的长度。
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
bool vis[maxn];//做标记的
char s[maxn],zk[maxn],yk[maxn];//s为输入的字符串,zk为左括号的栈,yk为右括号
int pos[maxn],ans,num;
int main(){scanf("%s",s+1);int n=strlen(s+1);yk[')']='(',yk[']']='[',yk['}']='{';for(int i=1;i<=n;i++){if(yk[s[i]]){if(yk[s[i]]==zk[num]){vis[i]=vis[pos[num]]=true;num--;//右括号与栈顶左括号配对,标记两端,弹出栈顶元素; }else num=0;//清空栈顶元素 }else{zk[++num]=s[i];pos[num]=i;}}int j; for(int i=1;i<=n;i++){if(vis[i]){for(j=i;j<=n;j++){if(!vis[j]) break;else vis[j]=false;}ans=max(ans,j-i);//对于每一个前面的为true的i,都只有一个对应的j,所以每一次都是碰到不满足的右括号时就先更新前面的长度。 }}cout<<ans<<endl;return 0;
}
这篇关于150. 括号画家 栈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!