LeetCode Longest Valid Parentheses 括号匹配
2015-12-06 20:51
211 查看
括号匹配问题一般的处理方式有两种:①使用栈的push/pop模拟;②给括号赋予正负的分值(+1/-1),从左到右计算分数之和。一个合法的串中任意位置的分数不会小于0(左括号数大于等于右括号)。
题意:给定一个由“(”和")"组成的字符串,求最长合法子串的长度。
栈一般用来判定括号序列是否合法,这里使用第二种方法。从左到右扫描一遍,遇到分数小于0则跳过该位置,从下一个位置起继续向右扫描,遇到分数为0的位置时则更新结果,处理代码如下:
但我们仅仅只能排除掉不合法的位置,获得“局部最优解”,最后剩下的串中左括号的数目可能大于右括号(最容易想到的情况是:起点处左括号刚好冗余),所以最优解可能包含在剩下的串中未进行更新。这种情况怎么处理呢?换个方向想一想,从左到右扫描,左括号的数目大于等于右括号;反过来,从右到左扫描,右括号的数目大于等于左括号,否则序列非法。所以对于剩下的串,只需从右往左扫描一次,就可以找出包含在其中的合法序列。
设从左到右扫描时,最后的待定串为
,则定有:
中任意位置处的分数都大于0,否则该位置要么被跳过、要么被更新。设
中最后一个')'的位置为
,则对所有
。则从右往左扫描时,这些
都会被跳过,然后从
开始进行计算,对其他位置同理。这是因为,从左到右
中任意位置的左括号大于右括号数,而这在从右往左扫描时,是非法的,这些非法的位置会被跳过,而合法的位置则会被更新。所以最后能得到正确的结果。代码如下:
题意:给定一个由“(”和")"组成的字符串,求最长合法子串的长度。
栈一般用来判定括号序列是否合法,这里使用第二种方法。从左到右扫描一遍,遇到分数小于0则跳过该位置,从下一个位置起继续向右扫描,遇到分数为0的位置时则更新结果,处理代码如下:
int l = 0, r = 0, sum = 0; int ans1 = 0; while(r < len){ sum += s[r] == '(' ? 1 : -1; if(sum < 0){ l = r + 1; sum = 0; } else if(sum == 0){ if(r - l + 1 > ans1) ans1 = r - l + 1; } ++r; }
但我们仅仅只能排除掉不合法的位置,获得“局部最优解”,最后剩下的串中左括号的数目可能大于右括号(最容易想到的情况是:起点处左括号刚好冗余),所以最优解可能包含在剩下的串中未进行更新。这种情况怎么处理呢?换个方向想一想,从左到右扫描,左括号的数目大于等于右括号;反过来,从右到左扫描,右括号的数目大于等于左括号,否则序列非法。所以对于剩下的串,只需从右往左扫描一次,就可以找出包含在其中的合法序列。
设从左到右扫描时,最后的待定串为
,则定有:
中任意位置处的分数都大于0,否则该位置要么被跳过、要么被更新。设
中最后一个')'的位置为
,则对所有
。则从右往左扫描时,这些
都会被跳过,然后从
开始进行计算,对其他位置同理。这是因为,从左到右
中任意位置的左括号大于右括号数,而这在从右往左扫描时,是非法的,这些非法的位置会被跳过,而合法的位置则会被更新。所以最后能得到正确的结果。代码如下:
class Solution { public: int longestValidParentheses(string s) { int len = s.size(), i = 0, j = len - 1; int l = 0, r = 0, sum = 0; int ans = 0; while(r < len){ sum += s[r] == '(' ? 1 : -1; if(sum < 0){ l = r + 1; sum = 0; } else if(sum == 0){ if(r - l + 1 > ans) ans = r - l + 1; } ++r; } int bound = l; r = len - 1, l = len - 1, sum = 0; int tmp = 0; while(l > bound){ sum += s[l] == '(' ? 1 : -1; if(sum > 0){ r = l - 1; sum = 0; } else if(sum == 0){ if(r - l + 1 > tmp) tmp = r - l + 1; } --l; } return ans > tmp ? ans : tmp; } };
相关文章推荐
- 基于TestNG 与Selenium 的自动化测试设计与实施
- 求两个字符串的编辑距离
- 智能硬件的时代划分
- 【Android】Android获取系统联系人
- 01 环境搭建-DirectX游戏开发
- Android - Input Controls
- Viterbi算法例子
- javascript必知必会之prototype
- 读书记-前言
- 安装 CentOS 后的系统配置及软件安装备忘
- request获取表单
- centos7折腾-安装桌面
- 剑指offer题21 包含min函数的栈
- linux su,sudo命令
- linux su,sudo命令
- TCP/IP详解之:TCP
- org.hibernate.PropertyAccessException: Exception occurred inside getter of ******——【hibernate 日常错误】
- CMMi, RUP (Rational Unified Process)与产品级敏捷在工程实践上有何不同?
- Microsoft 开源 Edge 浏览器的 javascript 引擎
- 一段语录