这是我参与更文挑战的第29天,活动详情查看: 更文挑战
前言
力扣第三十二题 最长有效括号 如下所示:
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = “(()”
输出:2
解释:最长有效括号子串是 “()”
示例 2:
输入:s = “)()())”
输出:4
解释:最长有效括号子串是 “()()”
示例 3:
输入:s = “”
输出:0
一、思路
这一题因为有这种一一对应的关系,所以第一眼看到就很自然的想到了使用 栈 来解决。
要想知道最长的有效括号有两个关键点,如下所示:
- 任何一个有效的括号都是以
)结尾 - 有效的括号的长度是
)的下标减去(的下标再加 1,举个例子()(())的长度是下标5 - 0 + 1 = 6
为了解决在迭代过程中无法得知子串的连续性,我们在栈底维护一个起始连续位置(官方称为最后一个右括号的位置)。这么做其实是为了解决类似于 ()(()) 的情况,栈只能知道最后一个 ) 匹配的是倒数第四个 (,栈无法知道在倒数第四个 ( 还有没有连续的有效字符串。所以起始时将栈底元素置为 -1,这样最后一个 ) 出栈时,用当前下标 5 - (-1) 即可得到结果 6。
对于连续性来讲,即使子串为
()((), 它也是连续的。还有什么时候会破坏连续性呢?就是当前出现了无法匹配的)时,如())(()),第三个元素)出现了无法匹配的情况,所以在第三个元素之后起始连续位置就变为了下标2
具体实现的话,主要就是在迭代字符串的过程中,会有以下两种情况:
- 碰到
(:将当前左括号的下标入栈 - 碰到
)先出栈- 如果栈为空:说明连续性被破坏,更新栈底元素为当前下标。
- 如果栈不为空:用当前下标减去栈顶元素的值就是当前
)对应的(中间的长度
举个例子
这里以 s = ())(()) 作为例子,具体的步骤如下所示:
- 初始化栈底元素
-1 - 开始迭代,获取到第一个字符
(。(的下标0入栈,此时栈中元素为0, -1 - 获取到第二个字符
)。栈顶0出栈,并用当前下标减栈顶元素1 - (-1) = 2,更新结果ret = 2 - 获取到第三个个字符
)。栈顶-1出栈,栈为空,更新栈底起始连续位置为2 - 获取到第四个字符
(。(的下标3入栈,此时栈中元素为3, 2 - 获取到第五个字符
(。(的下标4入栈,此时栈中元素为4, 3, 2 - 获取到第六个字符
)。栈顶4出栈,并用当前下标减栈顶元素5 - 3 = 2,无需更新结果 - 获取到第七个字符
)。栈顶3出栈,并用当前下标减栈顶元素6 - 2 = 4,更新结果ret = 4
二、实现
实现代码
实现代码与思路中保持一致
/**
* java使用栈实现
*/
public int longestValidParentheses(String s) {
int ret = 0;
Stack<Integer> stack = new Stack<>();
stack.push(-1);
for (int i=0; i<s.length(); i++) {
char c = s.charAt(i);
// 左括号入栈
if ('(' == c) {
stack.push(i);
} else { // 右括号有两种情况
stack.pop();
if (stack.isEmpty()) // 不匹配更新起始连续的位置
stack.push(i);
else // 更新结果
ret = Math.max(ret, i - stack.peek());
}
}
return ret;
}
复制代码
测试代码
public static void main(String[] args) {
int ret = new Number32().longestValidParentheses("()(()");
System.out.println(ret);
}
复制代码
结果

三、总结
没想到栈的执行用时击败率只有不到50%,这可是复杂度为 O(N) 啊,想想都不应该呀!冷静下来后看了下排名靠前的解法基本用的都是动态规划,时间复杂度虽然也是 0(N),我想应该是是不涉及到进栈出栈的操作导致效率比较高吧!
感谢看到最后,非常荣幸能够帮助到你~♥























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)