原題地址:https://leetcode.com/problems...面試
Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. For "(()", the longest valid parentheses substring is "()", which has length = 2. Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.
一個括號序列,求出其中成對括號的最大長度segmentfault
這題能夠參考個人另外一篇博客,這篇博客講解了如何用堆棧判斷括號序列是否能夠成對。咱們能夠將堆棧的思路延續到這裏。每當遇到一個左括號或者是沒法成對的右括號,就將它壓入棧中,能夠成對的括號則從棧中壓出。這樣棧中剩下的就是沒法成對的括號的下標。這時咱們能夠判斷這些下標間的距離來得到最大的成對括號長度。在這裏須要先遍歷一遍字符串,再遍歷一下非空的堆棧。數組
public int longestValidParentheses(String s) { Stack<Parenthese> parenthesesStack = new Stack<Parenthese>(); for(int i = 0 ; i < s.length() ; i++){ char symbol = s.charAt(i); if(symbol==')'){ //在這裏左右括號能夠成對,則出棧 if(!parenthesesStack.isEmpty() && parenthesesStack.peek().symbol=='('){ parenthesesStack.pop(); continue; } } //其餘狀況都壓入棧中 parenthesesStack.push(new Parenthese(symbol, i)); } int maxLength = 0; int nextIndex = s.length(); while(!parenthesesStack.isEmpty()){ int curIndex = parenthesesStack.pop().index; maxLength = (nextIndex-curIndex-1)>maxLength ? nextIndex-curIndex-1 : maxLength; nextIndex = curIndex; } return Math.max(nextIndex, maxLength); } public class Parenthese{ char symbol; int index; public Parenthese(char symbol, int index){ this.symbol = symbol; this.index = index; } }
在這裏能夠優化,由於使用數據結構不是必要的。咱們能夠直接壓入棧中下標,再從字符串中得到該下標對應的字符微信
public int longestValidParentheses_noDataStructure(String s) { Stack<Integer> parenthesesStack = new Stack<Integer>(); for(int i = 0 ; i < s.length() ; i++){ if(s.charAt(i)==')'){ if(!parenthesesStack.isEmpty() && s.charAt(parenthesesStack.peek())=='('){ parenthesesStack.pop(); continue; } } parenthesesStack.push(i); } int maxLength = 0; int nextIndex = s.length(); while(!parenthesesStack.isEmpty()){ int curIndex = parenthesesStack.pop(); int curLength = nextIndex-curIndex-1; maxLength = curLength>maxLength ? curLength : maxLength; nextIndex = curIndex; } return Math.max(nextIndex, maxLength); }
dynamic programming 的真 奧義其實在於假設已知以前全部的結果,結合以前的結果窮盡每一種當前值可能的狀況
在這道題目中,咱們假設已經知道長度爲n-1字符串中,到每個下標爲止的的最大的括號組長度,這些值被存儲在和字符串長度等長的int數組s中,其中s的下標表明字符串的下標,s的值表明到這個字符串下標爲止最長括號組長度。
那麼當前第n個符號主要有如下三種狀況:數據結構
代碼實現以下優化
public int longestValidParentheses_dynamicProgramming(String s) { int[] maxCount = new int[s.length()]; int maxLength = 0; for(int i = 1 ; i<s.length() ; i++){ if(s.charAt(i) == ')'){ if(s.charAt(i-1)=='('){ maxCount[i] = (i>=2? maxCount[i-2]+2 : 2); maxLength = Math.max(maxCount[i], maxLength); }else{ if(i-maxCount[i-1]-1>=0 && s.charAt(i-maxCount[i-1]-1)=='('){ maxCount[i] = maxCount[i-1]+2 + ((i-maxCount[i-1]-2 >= 0)?maxCount[i-maxCount[i-1]-2]:0);; maxLength = Math.max(maxCount[i], maxLength); } } } } return maxLength; }
簡化後的代碼以下:this
public int longestValidParentheses_dynamicProgrammingConcise(String s) { int[] maxCount = new int[s.length()]; int maxLength = 0; for(int i = 1 ; i<s.length() ; i++){ if(s.charAt(i) == ')' && i-maxCount[i-1]-1>=0 && s.charAt(i-maxCount[i-1]-1)=='('){ maxCount[i] = maxCount[i-1] + 2 + ((i-maxCount[i-1]-2>=0) ? maxCount[i-maxCount[i-1]-2] : 0); maxLength = Math.max(maxCount[i], maxLength); } } return maxLength; }
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~spa