「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。
题目:给定一个只包含(和)的字符串,要求找到最长的有效的括号字串的长度。
解题思路
之前做过判断括号是否有效以及找出生成符合规则的n对括号的题目,本题是给定一个不一定符合括号规则的字符串,需要判断其中是否含有正确规则括号,并且返回最长的那个字符的长度。判断是否为有效括号很简单,使用栈即可(遍历字符串,遇到左括号入栈,遇到右括号出栈),本题也可以使用栈来解决,思路如下:
- 首先判断输入字符串长度,小于2则不可能存在有效括号对。因为输入字符串存在可能开始就是右括号,因此初始化栈需要事先加入一个元素,而栈中记录的是有效括号的范围,因此该数字不是任意的,如果输入字符为
(),有效括号长度为2,循环到右括号时i为1,因此可以设置栈底元素为-1,此时1-(-1)即为最终结果。 - 遍历字符串,当遇到左括号将左括号下标入栈(栈中下表代表有效字符的起始),遇到右括号从栈中弹出一个元素。
- 若之后栈不为空,则计算当前有效字串长度,和事先设置的最大长度进行比较,更新最大字串长度。若栈为空,则自上一次有效字符之后出现了无效字符,此字符分割了两个有效字符(不连续),有效字符起点需要更新。
- 最终更新结果即为循环到的右括号索引减去栈顶元素的值。
代码如下:
public int longestValidParentheses(String s) {
if(s.length()<2) return 0;
int maxlen = 0;
Stack<Integer> stack = new Stack<>();
stack.push(-1);
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='('){
stack.push(i);
}else {
stack.pop();
if(!stack.isEmpty()){
maxlen = Math.max(maxlen, i-stack.peek());
}else {
stack.push(i);
}
}
}
return maxlen;
}
该算法时间复杂度为,空间复杂度为。
动态规划解法
官方实现还有动态规划解法(暂时也不是很理解动态规划。。。直觉就是找递推式,找到就nb)。参考一个发布题解的大佬的解题过程:
动态规划解法。包含详细解析。