原题链接在这里:https://leetcode.com/problems/longest-valid-parentheses/
题目:
Given a string containing just the characters
'('
and ')'
, find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"
Example 2:
Input: " )()()) "
Output: 4
Explanation: The longest valid parentheses substring is "()()"
题解:
这道题是求最长的括号序列,比较容易想到用栈这个数据结构。基本思路就是维护一个栈,遇到左括号就进栈,遇到右括号则出栈,并且判断当前合法序列是否为最 长序列。不过这道题看似思路简单,但是有许多比较刁钻的测试集。具体来说,主要问题就是遇到右括号时如何判断当前的合法序列的长度。比较健壮的方式如下:
(1) 如果当前栈为空,则说明加上当前右括号没有合法序列(有也是之前判断过的);
(2) 否则弹出栈顶元素,如果弹出后栈为空,则说明当前括号匹配,我们会维护一个合法开始的起点start, 合法序列的长度即为当前元素的位置 i-start+1; 否则如果栈内仍有元素,那肯定是"(". 合法序列就会从这个"("下一位开始. 长度为当前栈顶元素的位置的下一位到当前元素的距离. i-(stk.peek()+1)+1. 因为栈顶元素后面的括号对肯定是合法的, 而 且左括号出过栈了。
Time Complexity: O(n). Space: O(n).
AC Java:
1 public class Solution {
2 public int longestValidParentheses(String s) {
3 if(s == null || s.length() == 0){
4 return 0;
5 }
6
7 int res = 0;
8 int start = 0;
9
10 Stack<Integer> stk = new Stack<Integer>();
11 for(int i = 0; i<s.length(); i++){
12 if(s.charAt(i) == '('){
13 stk.push(i);
14 }else{
15 //遇到')',但是stack是空的,说明不合法,更新 start 到 i+1
16 if(stk.isEmpty()){
17 start = i+1;
18 }else{
19 //否则弹出栈顶
20 stk.pop();
21 //剩下的stack为空,说明到start 到 i是合法括号对
22 if(stk.isEmpty()){
23 res = Math.max(res, i-start+1);
24 }else{
25 //身下的stack不为空,说明当前stack的栈顶 后面的括号对才是合法的
26 res = Math.max(res, i-stk.peek());
27 }
28 }
29 }
30 }
31 return res;
32 }
33 }
分别计数遇到的"(" 和")"的个数l 和 r. 先从左向右扫, l == r时跟新维护res. 当r大于l 时不合法重置为0.
在反过来从右向左扫一次.
为什么不能一次呢. e.g. ()((). 中间出现不合法, 若最后及时r比l小, 但取出r*2. 答案就是4. 正解应该是2.
1 class Solution {
2 public int longestValidParentheses(String s) {
3 if(s == null || s.length() == 0){
4 return 0;
5 }
6
7 int res = 0;
8 int l = 0;
9 int r = 0;
10 for(int i = 0; i<s.length(); i++){
11 if(s.charAt(i) == '('){
12 l++;
13 }else{
14 r++;
15 }
16
17 if(l == r){
18 res = Math.max(res, r*2);
19 }else if(r > l){
20 l = 0;
21 r = 0;
22 }
23 }
24
25 l = 0;
26 r = 0;
27 for(int i = s.length()-1; i>=0; i--){
28 if(s.charAt(i) == '('){
29 l++;
30 }else{
31 r++;
32 }
33
34 if(l == r){
35 res = Math.max(res, r*2);
36 }else if(l > r){
37 l = 0;
38 r = 0;
39 }
40 }
41 return res;
42 }
43 }