Longest valid parentheses method induction, longestparentheses
Leetcode: I will introduce three methods below:
Method 1: Search for matching without stacks
Create an array l2 to indicate matching, and then I start from 0, see (then record the value corresponding to l2 as-1 until it is seen), find, starting from the current I, return to find out if there is a match, as shown in the following figure.) check whether the corresponding Location Value of the current l2 is-1, if it is not, jump to the position of the corresponding value, continue to find until the first (, set the corresponding l2 value to this time (subscript, for the next operation) is found. If it is-1, the value of the corresponding location of the current l2 is also set to-1, indicating no redundant matching. After traversing, obtain the complete array l2. In this case, obtain the maximum legal match from l2. For example:
For string :)(())()(
First read the right parenthesis, but at this time I = 0, there cannot be a match on the left, so l2 [0] =-1
Then read the left parentheses, l2 [1] =-1, l2 [2] =-1
Now read the right parenthesis and look forward from the current position. The first is the left parenthesis, so l2 [3] = 2 (the subscript of the left parenthesis at this time)
Then I read the right parenthesis, and looked forward from the current position. First I saw the right brace. The l2 value corresponding to the right brace is not-1, then it is adjusted to the position of the corresponding value-1, in this example, jump to the position where the subscript is 1 and read a left bracket, so l2 [4] = 1
In this example, l2 = {-1,-1,-, 1,-,-1}
We can see that the correspondence between subscript and value in l2 is the correspondence between two matching parentheses in the original string. Therefore, we will take this correspondence out: 3-2, 4-1, 6-5. Sort these values and obtain the values 1, 2, 3, 4, 5, 6. We can see the required value, that is, the maximum length of the sequence in This sorting (this sequence increases with 1 as an equal deviation ). For example, 1, 2, 3, 4, 5, 6, 9, 10, 11, 12 have two sequences: 1, 2, 3, 4, 5, 6, 9, 10, 11, 12. The length of the longest sequence is what we want.
The Code is as follows:
public int longestValidParentheses(String s) { int max=0; int[] l2=new int[s.length()]; char[] ch=s.toCharArray(); for(int i=0;i<ch.length;i++){ if(ch[i]=='('){l2[i]=-1;} else{ for(int j=i-1;j>=0;){ if(ch[j]==')'&&l2[j]!=-1){ j=l2[j]-1; if(j<0){l2[i]=-1;break;} } else if(ch[j]==')'&&l2[j]==-1){l2[i]=-1;break;} else if(ch[j]=='('){l2[i]=j;break;} } if(i==0&&ch[0]==')'){l2[i]=-1;} } } List<Integer>l3=new ArrayList<Integer>(); for(int i=0;i<s.length();i++){ if(l2[i]!=-1){l3.add(l2[i]);l3.add(i);} } Collections.sort(l3); int inter=0; for(int i=0;i<l3.size()-1;i++){ if(l3.get(i+1)==l3.get(i)+1){inter++;max=Math.max(inter, max);} else {max=Math.max(inter, max);inter=0;} } return max>0?max+1:0; }
The program can pass, but it does not run fast. The reason is that the List is used at last, which slows down the speed. For example, if you use an array, it will be faster. I have used many methods to solve this problem and found that almost none of the List functions have been used. As long as I replace the List method with an array, I can use it... Oh, it's a good idea for the scammers.
Method 2: Use stack to find matching
This method is much simpler. Two stacks, one used to press the Left and Right brackets, and the other used to press the subscript. When we see the left brackets, we press them in. When we see the right brackets, we can judge them. This is relatively simple. You can directly paste the code for reference:
public int longestValidParentheses(String s) { int len=s.length(); int max=0; Stack<Character> t1 = new Stack<Character>(); Stack<Integer> t2 = new Stack<Integer>(); for(int i=0;i<len;i++){ if(s.charAt(i)=='('){ t1.push('('); t2.push(i); } else{ if(t1.size()>0 && t1.peek().equals('(')){ t1.pop(); t2.pop(); int tmp=t2.size()==0?i+1:i-t2.peek(); max=Math.max(max,tmp); } else{ t1.push(')'); t2.push(i); } } } return max; }
The stack is used, and it does not run fast...
Method 3: Dynamic Planning
The core of dynamic planning is to find the structure of the optimal subproblem and check whether there are repeated computing subproblems. In this question, if a string is the longest legal string, it must be constructed by another substring. From the start of string s, we consider every position on s. If the character at this position is included in the largest birthdate string, then we can construct a maximum of valid substrings of the substring starting with 1st elements. In other words, dp [I] indicates from s [I] to s [s. length-1] The longest valid length of the substring that contains s [I]. If s [I] = '(', from I to s. length-1 calculates the value of dp [I. In s, find the valid parentheses starting from I + 1 to match the length of the substring, that is, dp [I + 1]. Skip this valid parenthesis substring and check the next character, its subscript is j = I + 1 + dp [I + 1]. If j does not cross the border and s [j] = ')', then s [I... j] is the matching of valid parentheses, dp [I] = dp [I + 1] + 2. After obtaining s [I... after the valid matching length of j], if j + 1 does not cross the border, the value of dp [I] must be added with the longest valid matching starting from j + 1, that is, dp [j + 1].
int longestValidParentheses(String s) { int len = s.length(); if(len<2) return 0; int max = 0; int []dp = new int[len];for(int i = len-2;i>=0;i--) { if(s.charAt(i) == '(') { int j = i+1+dp[i+1]; if(j<len && s.charAt(j) == ')') { dp[i] = dp[i+1] + 2; if(j+1<len) dp[i] += dp[j+1]; } if(dp[i]>max) max = dp[i]; } } return max; }
This method is faster than the first two methods...