-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLeetCode-32-Longest-Valid-Parentheses.java
151 lines (136 loc) · 4.89 KB
/
LeetCode-32-Longest-Valid-Parentheses.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
Analysis:
1.O(n) with one Stack
2.Converting '(',')' into 1/0 code
https://discuss.leetcode.com/topic/37982/my-easy-o-n-java-solution-with-explanation
3.Forward and backward pass
https://discuss.leetcode.com/topic/22287/constant-space-o-n-time-with-forward-and-backward-pass
4.DP, O(n)
https://discuss.leetcode.com/topic/2289/my-o-n-solution-using-a-stack/6
*/
public class Solution {
//1.O(n) with one Stack
// public int longestValidParentheses(String s) {
// int max = 0;
// Stack<Integer> stack = new Stack<Integer>();
// int l = -1; // the (l+1,i) is the longest valid parentheses with s.charAt(i) as last char, so l is the index just left of valid parentheses
// for(int i = 0; i < s.length(); i++){
// if(s.charAt(i) == '(') stack.push(i);
// else{
// // now, s.charAt(i) == ')'
// if(stack.isEmpty()) l = i;
// else{
// stack.pop();
// if(stack.isEmpty()) max = Math.max(max, i - l);
// else max = Math.max(max, i - stack.peek());
// }
// }
// }
// return max;
// }
// 1.Another O(n) with one Stack
// public int longestValidParentheses(String s) {
// int max = 0;
// Stack<Integer> stack = new Stack<Integer>();
// stack.push(-1); //initialize Stack with index just left of curr index
// for(int i = 0; i < s.length(); i++){
// // here, stack.size() > 1 not '>= 1', as we initialized stack with -1
// if(s.charAt(i) == ')' && stack.size() > 1 && s.charAt(stack.peek()) == '('){
// stack.pop();
// max = Math.max(max, i - stack.peek());
// }else{
// stack.push(i);
// }
// }
// return max;
// }
//2.Convert '()(()' to '11011', and calculate the length longest '1' substring
// public int longestValidParentheses(String s) {
// int max = 0;
// Stack<Integer> stack = new Stack<Integer>();
// int[] arr = new int[s.length()];
// // convert '('&')' to '1'&'0'
// for(int i = 0; i < s.length(); i++){
// char ch = s.charAt(i);
// if(ch == '(') stack.push(i);
// else{
// if(!stack.isEmpty()){
// arr[i] = 1;
// arr[stack.pop()] = 1;
// }
// }
// }
// // now we convert '()(()' to '11011', we need to calculate the max length of continuous 1
// int temp = 0;
// for(int i : arr){
// if(i == 1) temp++;
// else{
// max = Math.max(max, temp);
// temp = 0;
// }
// }
// // we cannot directly output max here, as it's possible that the last continuous 1 substring is the max one
// // e.g. "()" -> 2, if we directly return max, it would return 0
// return Math.max(max, temp);
// }
// 3.Forward and backward pass
// public int longestValidParentheses(String s) {
// int max = 0;
// int extra = 0;
// int len = 0;
// // Forward pass
// for(int i = 0; i < s.length(); i++){
// if(s.charAt(i) == '('){
// extra++;
// len++;
// }else{
// if(extra > 0){
// extra--;
// len++;
// if(extra == 0) max = Math.max(max, len);
// }else{
// extra = 0;
// len = 0;
// }
// }
// }
// // Backward pass
// extra = 0;
// len = 0;
// for(int i = s.length() - 1; i >= 0; i--){
// if(s.charAt(i) == ')'){
// extra++;
// len++;
// }else{
// if(extra > 0){
// extra--;
// len++;
// if(extra == 0) max = Math.max(max, len);
// }else{
// extra = 0;
// len = 0;
// }
// }
// }
// return max;
// }
// 4.DP
public int longestValidParentheses(String s) {
int max = 0;
char[] chars = s.toCharArray();
int[] state = new int[chars.length];
int open = 0;
for(int i = 0; i < chars.length; i++){
if(chars[i] == '(') open++;
if(chars[i] == ')' && open > 0){
// match found
state[i] = 2 + state[i - 1];
// add matches to previous
if(i - state[i] > 0) state[i] += state[i - state[i]];
open--;
}
max = Math.max(max, state[i]);
}
return max;
}
}