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 }

类似Largest Rectangle in Histogram. 

posted @ 2015-09-17 23:24  Dylan_Java_NYC  阅读(359)  评论(0编辑  收藏  举报