(重点)[LeetCode]Longest Valid Parentheses
来源:互联网 发布:家电 进销存 源码 编辑:程序博客网 时间:2024/06/05 00:10
Question:
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.
本题难度hard。有两种算法分别是:stack和DP。
算法1:stack
【复杂度】
时间 O(N) 空间 O(N)
【思路】
用Stack的方法本质上和Valid Parentheses是一样的,一个右括号能消去Stack顶上的一个左括号。不同的是,为了能够计算括号对的长度我们还需要记录括号们的下标。这样在弹出一个左括号后,我们可以根据当前坐标减去栈中上一个(也就是Pop过后的Top元素)的坐标来得到该有效括号对的长度。
【附】
这个算法难在对各种情况的判断,以及对stack的巧妙利用。这个算法我是看了很一会才反应过来((⊙﹏⊙)b)。下面将代码贴出,对于各种情况的处理我也进行了注释。
【注意】
第26行:curLen=i-stack.peek().index;
不能是curLen=i-stack上一个pop出的index+1;
。如果对于)()()
,此时 i=4,如果按照后一种方法,算出的curLen=i-3+1
,而正确的应该是curLen=i-0
。
【代码】
public class Solution { public int longestValidParentheses(String s) { //require if(s==null) return 0; int size=s.length(); if(size<2) return 0; int ans=0; Stack<Parenthese> stack=new Stack<Parenthese>(); //invariant for(int i=0;i<size;i++){ char c=s.charAt(i); //遇到左括号,将其push进栈 if(c=='(') stack.push(new Parenthese(c,i)); else{ //遇到右括号,分类讨论 //如果当前栈顶是左括号,则消去并计算长度 if(!stack.isEmpty()&&stack.peek().c=='('){ int curLen=0; stack.pop(); if(stack.isEmpty()) // ()( ) curLen=i+1; else // ((() ) or )()( ) curLen=i-stack.peek().index; ans=Math.max(ans,curLen); }else // ) or ) ) //如果栈顶是右括号或者是空栈,则将右括号也push进栈,它的坐标将方便之后计算长度 stack.push(new Parenthese(c,i)); } } //ensure return ans; } class Parenthese{ char c; int index; public Parenthese(char c,int index){ this.c=c; this.index=index; } }}
算法2:DP
【复杂度】
时间 O(N) 空间 O(N)
【思路】
动态规划法将大问题化为小问题,我们不一定要一下子计算出整个字符串中最长括号对,我们可以先从后向前,一点一点计算。假设d[i]是从下标i开始到字符串结尾最长括号对长度,s[i]是字符串下标为i的括号。如果s[i-1]是左括号,如果i + d[i] + 1是右括号的话,那d[i-1] = d[i] + 1。如果不是则为0。如果s[i-1]是右括号,因为不可能有右括号开头的括号对,所以d[i-1] = 0。
【附】
我只能再次感慨DP的强大和这个算法的精妙。
【注意】
1、第16行if(end<size&&s.charAt(end)==')'){
中的end<size
必须要有,以防止(()
(当i=0,end=3越界)
2、第19行d[i]+=d[end+1];
,别错写为d[i]+=d[end];
【代码】
public class Solution { public int longestValidParentheses(String s) { //require if(s==null) return 0; int size=s.length(); if(size<2) return 0; int ans=0; int[] d=new int[size]; //invariant for(int i=size-2;i>=0;i--){ char c=s.charAt(i); if(c=='('){ int end=i+d[i+1]+1; if(end<size&&s.charAt(end)==')'){ // (()) d[i]=d[i+1]+2; if(end+1<size) // ()() or ((())()) d[i]+=d[end+1]; } } ans=Math.max(ans,d[i]); } //ensure return ans; }}
参考
Longest Valid Parentheses(这篇帖子无论是技术探索精神还是写作风格都值得参考)
- (重点)[LeetCode]Longest Valid Parentheses
- LeetCode: Longest Valid Parentheses
- LeetCode Longest Valid Parentheses
- LeetCode: Longest Valid Parentheses
- [Leetcode] Longest Valid Parentheses
- [leetcode]longest Valid Parentheses(!!)
- [Leetcode] Longest Valid Parentheses
- leetcode Longest Valid Parentheses
- 【leetcode】Longest Valid Parentheses
- [LeetCode]Longest Valid Parentheses
- [leetcode] Longest Valid Parentheses
- LeetCode-Longest Valid Parentheses
- [LeetCode] Longest Valid Parentheses
- LeetCode:Longest Valid Parentheses
- Leetcode: Longest Valid Parentheses
- Leetcode:Longest Valid Parentheses
- leetcode Longest Valid Parentheses
- leetcode Longest Valid Parentheses
- hdu 5924/Mr. Frog’s Problem
- 使用JDBC构建简单的数据访问层
- HDU2017--字符串统计
- 不利用函数直接构造链表
- java——进制的转换
- (重点)[LeetCode]Longest Valid Parentheses
- Java中的异常学习
- Java垃圾回收机制
- HDU 3560 Graph’s Cycle Component(并查集)
- Ural1297Palindrome最长回文串.manacher解法
- Leetcode-69. Sqrt(x)
- 黑客的日常生活是怎样的?论黑客的道德与操守
- Java入门第二季-2.封装
- 409.leetcode Longest Palindrome(easy)[字符串处理 最长回文]