原题链接
题意
给出1个长度为n的括号序列,大中小6种字符。
美观的括号序列定义为:
(1) 空序列;
(2) 若括号序列A是美观的,则括号序列 (A)、[A]、{A} 也是美观的;
(3) 若括号序列A、B都是美观的,则括号序列AB也是美观的。
例如 [(){}]()
是美观的括号序列,而)({)[}](
则不是。
求长度最大的美观序列长度。
\(1 \leq n \leq 10^5\)
本人题解
总体思考:嵌套括号序列很有子问题的味道
不妨简化1下问题。
当只有嵌套1种情况时,怎么做?找到相邻的括号(形如()[]{})向外扩展求得嵌套的极大区间。
能够合并区间时,怎么做?区间恰好相邻,则可以自然地相连。
然后,可以在连接的产物外面继续套括号;若将连接的产物看作已经完成的子问题而直接删去,则相当于再次执行第1步:直接匹配括号。
不难发现,这是1个循环往复的过程。统一化的表达就是:每次找到1对直接匹配的相邻括号,删去它。(即令前驱指向后继,并将匹配位置移向前驱继续尝试匹配)。
完成所有删除操作后,存在的元素中,两两下标差值最大值即为所求。
删除操作使用链表实现。时间复杂度\(O(n)\)。代码见此
普遍解法
从左到右逐步考虑,第\(i\)个元素前的待匹配序列可用1个栈来维护。若\(i\)与栈顶能够匹配,则弹出栈顶元素。
归结起来,正是由于括号序列的递归性和完整性,使用栈进行动态维护最为恰当。
括号序列的外延
假设只有1种括号(),那么在构造括号序列的过程中,只需要满足任意时刻左括号个数大于等于右括号个数。
原因:只有1种括号,因而不管括号怎样”交叉“放置,都可以视为嵌套/相连。例如\([(])\)不是括号序列,但\((())\)是括号序列。故只要右括号左边有空闲的左括号,就一定可以匹配成功;否则匹配失败,一定不成功。