最长合法括号子序列
最长合法括号子序列
一个合法的括号序列满足以下条件:
- 序列()被认为是合法的。
- 如果序列X与Y是合法的,则XY也被认为是合法的。
- 如果序列X是合法的,则(X)也是合法的。
例如, () , ()() , (()) 这些都是合法的。
现在,给定一个由 ( 和 ) 组成的字符串。
请你求出其中的最长合法括号子序列的长度。
注意,子序列不一定连续。
输入格式
共一行,一个由 ( 和 ) 组成的字符串。
输出格式
一个整数,表示最长合法括号子序列的长度。
数据范围
前五个测试点满足,。
所有测试点满足,。
输入样例1:
(()))(
输出样例1:
4
输入样例2:
()()(()(((
输出样例2:
6
解题思路
这是一个括号序列的问题。对于一个合法的括号序列,有两个结论:
- 整个序列的左右括号数量相等。
- 任意一个前缀中,左括号的数量大于等于右括号的数量。
对于这两个条件,一般用一个计数器来实现。一开始,遇到左括号就,遇到右括号就。等价于在上面的第个条件中,最后的;第个条件中,整一个操作的过程都始终满足。
一个合法括号序列最长,等价于右括号数量最多(因为左右括号数量相同),因此我们只需要找到一个合法括号序列,使得右括号的数量最多就可以了。
贪心的思想是,对于右括号,能选则选。如果在遍历的过程中遇到右括号,且,就选这个右括号。下面证明一下这种做法是正确的。
首先有贪心解最优解,因为贪心解是合法解,最优解是合法解中最大的那一个,因此贪心解最优解。
下面证明贪心解最优解。反证法,假设有最优解贪心解。
因此可以证明得到贪心解最优解,贪心解最优解,即可以证明贪心解最优解。
AC代码如下:
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 const int N = 1e6 + 10; 6 7 char str[N]; 8 9 int main() { 10 scanf("%s", str); 11 12 int l = 0, r = 0; 13 for (int i = 0; str[i]; i++) { 14 if (str[i] == '(') l++; 15 else if (l > 0) l--, r++; 16 } 17 18 printf("%d", r << 1); 19 20 return 0; 21 }
参考资料
AcWing 4207. 最长合法括号子序列(AcWing杯 - 周赛):https://www.acwing.com/video/3660/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16095166.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效