LeetCode 32. Longest Valid Parentheses
原题链接在这里: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. ((). 中间出现合法, till the end, there will be no l == r, thus give the wrong answer as 0. But correct answer is 2. Time Complexity: O(s.length()). Space: O(1).
AC Java:
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 }