longest valid parentheses方法归纳
题目大意见leetcode,下面我稍微介绍下想到的三种方法:
方法一:不用栈去找匹配
建立一个数组l2表示匹配,然后i从0开始,看到 ( 就把l2对应的数值记为-1,直到看到 ),找到)以后,从当前i开始返回去找是否有匹配,此时如读到),就看当前的l2的对应位置值是否为-1,如果不是就跳转到所对应的值的位置,继续往前找,直到找到第一个(,将l2对应值置为此时(的下标,进行下一次操作。如果是-1,就把当前l2对应位置的值也置为-1,表示没有多余的匹配。遍历一遍后,得到完整的数组l2,此时需要从l2得到最大的合法匹配。举个例子:
对于字符串:)(())()(
首先读到右括号,但是此时i=0,左边不可能有匹配,所以l2[0]=-1
接着读到左括号,l2[1]=-1,l2[2]=-1
此时读到右括号,从当前位置往前找,第一个就是左括号,所以l2[3]=2(此时左括号的下标)
接着又读到右括号,从当前位置往前找,先看到了右括号,此右括号的位置对应的l2值不为-1,则调到对应值-1的位置,此例子中跳到下标为1的位置,读到一个左括号,所以l2[4]=1
以此类推,此例中l2={-1,-1,-1,2,1,-1,5,-1}
下面涉及到回复,我们可以看到l2中下标与值的对应就是原字符串中匹配的两个左右括号的对应,所以,此时,我们把这个对应拿出来:3-2,4-1, 6-5。把这些值进行排序,得到1,2,3,4,5,6,可以看出要求的值,即为此排序中最大那个序列的长度(此序列以1为等差递增)。如1,2,3,4,5,6,9,10,11,12中有两个序列1,2,3,4,5,6和9,10,11,12.而最长的那个序列的长度即为我们所求。
代码如下:
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;
}
程序能通过,但是跑的并不快,原因在于最后用了List,导致速度变慢了,如全用数组实现,会快一些。这个题目我用过好多办法,发现几乎使用List都没过,只要一把List的方式换成数组,就能过。。。呵呵,给偷懒者当头一棒。
方法二:用栈去找匹配
这种方法就简单很多了,两个栈,一个用来压入左右括号,另一个压下标。看到左括号就压进去,看到右括号就进行判断,比较简单,直接贴代码参考吧:
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;
}
用了栈,跑的也不快。。。
方法三:动态规划
动态规划的核心在于找到最优子问题的结构和看是否有重复计算的子问题。此题中,如果一个字串是最长的合法串,那么它一定能由另一个子串构造。从字符串s有后往前,我们考虑s上的每一个位置,要是这个位置的字符包含在最长子串中,则我们可以由这个子串的从第1个元素开始的子串的最大合法子串构造。换言之,dp[i]表示从s[i]到s[s.length - 1] 包含s[i] 的最长的有效匹配括号子串长度,在s中从后往前,若s[i] == '(',则在s中从i开始到s.length - 1计算dp[i]的值。在s中寻找从i + 1开始的有效括号匹配子串长度,即dp[i + 1],跳过这段有效的括号子串,查看下一个字符,其下标为j = i + 1 + dp[i + 1]。若j没有越界,并且s[j] == ‘)’,则s[i ... j]为有效括号匹配,dp[i] =dp[i + 1] + 2。在求得了s[i ... j]的有效匹配长度之后,若j + 1没有越界,则dp[i]的值还要加上从j + 1开始的最长有效匹配,即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;
}
这个方法的速度相比前两种方法简直飞起。。。
longest valid parentheses方法归纳的更多相关文章
- 【leetcode】 Longest Valid Parentheses (hard)★
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- Java for LeetCode 032 Longest Valid Parentheses
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- Longest Valid Parentheses(最长有效括号)
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- 32. Longest Valid Parentheses
题目: Given a string containing just the characters '(' and ')', find the length of the longest valid ...
- [LeetCode] Longest Valid Parentheses 解题思路
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- Longest Valid Parentheses——仍然需要认真看看(动态规划)
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- Longest Valid Parentheses - LeetCode
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- LeetCode 之 Longest Valid Parentheses(栈)
[问题描写叙述] Given a string containing just the characters '(' and ')', find the length of the longest v ...
- 刷题32. Longest Valid Parentheses
一.题目说明 题目是32. Longest Valid Parentheses,求最大匹配的括号长度.题目的难度是Hard 二.我的做题方法 简单理解了一下,用栈就可以实现.实际上是我考虑简单了,经过 ...
随机推荐
- 可以在手机上看电脑本地html步骤,我自己总结的哦!
1.打开控制面板 2.打开程序和功能 3.打开或关闭功能 4.internet信息服务展开后里面所有的都要选中 5.回到桌面,然后右键计算机,选择'管理' 6.先在E盘或者D盘创建一个文件夹,自己随意 ...
- SQL Server学习之路(三):“增删改查”之“增”
0.目录 1.前言 2.通过SSMS添加数据 3.通过SQL语句添加数据 3.1 添加单条数据 3.2 添加多条数据 4.通过其他表导入数据 4.1 通过数据库中的其他表导入数据 4.2 通过exce ...
- Netty4 学习笔记之四: Netty HTTP服务的实现
前言 目前主流的JAVA web 的HTTP服务主要是 springMVC和Struts2,更早的有JSP/servlet. 在学习Netty的时候,发现Netty 也可以作HTTP服务,于是便将此整 ...
- Linux下批量修改文件名方法
对于在Linux中修改文件名的方式一般我们会用mv命令进行修改,但是mv命令是无法处理大量文件修改名称. 但是在处理大量文件的时候该如何进行批量修改呢? 方法一:mv配合for循环方式进行修改 [ro ...
- JavaScript实现策略模式
在开篇之前先分享今天看到的一句关于设计模式的话:将不变的部分和变化的部分隔开是每个设计模式的主题 请大家自行感受这句话的精髓所在,并且思考学习设计模式究竟能给我们编程带来什么样的东西,欢迎大家在文章下 ...
- ajax接受json响应(讲义)
l 什么是json? l Json和xml比较 l Ajax如何使用JSON l Ajax接收json响应案例 什么是json? JSON (JavaScript Object Notation) 是 ...
- ajax_get/post_两级联动
使用ajax实现菜单联动 通常情况下,GET请求用于从服务器上获取数据,POST请求用于向服务器发送数据. 需求:选择第一个下拉框的值,根据第一个下拉框的值显示第二个下拉框的值 首先使用GET方式. ...
- Maven依赖的是本地工程还是仓库jar包?
相信大家都碰见过maven配置的依赖或者是jar包或者是工程,在开发的过程当中,我们当然需要引入的是工程,这样查看maven依赖的文件的时候,就能直接查看到源码. 一.本地工程依赖 举个例子,其架构如 ...
- C#设计模式之二十一职责链模式(Chain of Responsibility Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第八个模式,该模式是[职责链模式],英文名称是:Chain of Responsibility Pattern.让我们看看现实生活中 ...
- MD5加密--Java
MD5 Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护.该算法的文件号为RFC 1321(R.R ...