题目链接:https://leetcode.com/problems/longest-valid-parentheses/description/

题目大意:找出最长的括号匹配的子串长度。例子:"(()("长度是2;"()()(())"长度是8

解法一:利用三层for循环,逐一的找每一个子串,并判断每一个子串是否是括号匹配的。很遗憾,超时了。代码如下:

     public int longestValidParentheses(String s) {
int res = 0;
for(int i = 0; i < s.length(); i++) {//逐一查看每一个子串
for(int j = i + 2; j <= s.length(); j += 2) {
int cnt = parentheses(s.substring(i, j));
if(res < cnt) {
res = cnt;
}
}
}
return res;
}
//判断是否是括号匹配的
public static int parentheses(String s) {
Stack<Character> st = new Stack<Character>();
int cnt = 0;
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(c == ')') {
if(!st.isEmpty() && st.peek() == '(') {
cnt++;
st.pop();
}
else {
return 0;
}
}
else {
st.push(c);
}
}
if(!st.isEmpty()) {
return 0;
}
return cnt * 2;
}

解法二(借鉴):用栈存储左括号下标,而不是'('左括号。如果是'(',则将下标压栈。如果是')',则查看栈的情况,如果栈空,则记录下一个子串开始的位置下标(即i+1);如果非空,则查看栈中元素情况,如果只有一个'(',则弹出计数子串长度,如果有多个'(',则计数到目前为止的匹配的子串长度情况。或者同时压栈存储左括号和右括号下标,当遇到')',则查看栈顶元素,如果是'(',则计数,否则压栈。这两种方法都是o(n)的时间复杂度。代码如下(耗时26ms):

第一种压栈左括号下标的方法:

 public int longestValidParentheses(String s) {
Stack<Integer> st = new Stack<Integer>();//存'('下标
int res = 0, lastIndex = 0, length = s.length();
for(int i = 0; i < length; i++) {
char c = s.charAt(i);
if(c == '(') {//如果是'(',将下标压栈
st.push(i);
}
else {//如果是')',分情况讨论
if(st.isEmpty()) {//如果为空,则出现')'没有'('匹配的情况,则当前子串结束,下一个子串的开始位置即是当前子串结束的下一个位置
lastIndex = i + 1;
}
else {//如果非空,可能出现两种情况:'()'或'(())'
st.pop();
if(st.isEmpty()) {//如果为空,则说明栈中没有'('需要匹配
res = Math.max(res, i - lastIndex + 1);
}
else {//如果非空,则当前栈中还有'('存在
res = Math.max(res, i - st.peek());
}
}
}
}
return res;
}

第二种压栈左括号和右括号下标的方法(基本与上面第一种一样):

     public int longestValidParentheses(String s) {
Stack<Integer> st = new Stack<Integer>();
int res = 0, length = s.length();
for(int i = 0; i < length; i++) {
if(s.charAt(i) == '(') {//左括号压栈下标
st.push(i);
}
else {//遇到右括号
if(st.isEmpty()) {//如果栈空,则压栈右括号下标
st.push(i);
}
else {
if(s.charAt(st.peek())== '(') {//如果栈顶元素是左括号,则匹配,退栈计数子串长度
st.pop();
res = Math.max(res, (i - (st.isEmpty() ? -1 : st.peek())));
}
else {//如果栈顶元素是右括号,则压栈右括号下标
st.push(i);
}
}
}
}
return res;
}

解法三:利用dp。首先dp[i] 表示从s[i]往前推最长能匹配的子串,换句话说,就是到s[i]为止的最长匹配子串后缀。那么当对于下面几种情况进行分析:

1. s[i] ==’(’     s[i]为左括号,dp[i]=0这个很好理解。
2. s[i] ==’)’  这就要分情况了
  a) 如果s[i-1]是’(’说明已经完成了一次匹配,子串长度为2,但是还要加上dp[i-2]的大小,也就是当前匹配的这对括号前面的最长匹配长度,它们是相连的。
  b) 如果s[i-1]是’)’这样不能匹配,则需要考虑s[i-1-dp[i-1]]的情况了,如果s[i-1-dp[i-1]]是一个左括号,则与当前右括号匹配,那么此时我们令dp[i]=dp[i-1]+2,这个2就是刚刚匹配的左右括号。最后还要把dp[i-2-dp[i-1]](即与当前括号')'匹配的'('前面一个位置的dp长度,它们是相连的)值加起来,把相连的最大长度求出来。代码如下(耗时20ms):

     public int longestValidParentheses(String s) {
int length = s.length();
int[] dp = new int[length];
int res = 0;
for(int i = 0; i < length; i++) {
dp[i] = 0;
if(s.charAt(i) == ')' && (i - 1) >= 0) {
if((i - 1) >= 0 && s.charAt(i - 1) == '(') {//如果前一个位置与当前括号')'匹配
dp[i] = 2;//暂且只计算匹配的'('')'
if(i - 2 >= 0) {//加上与')'匹配的'('前一个位置的dp匹配长度
dp[i] += dp[i - 2];
}
}
else {//如果前一个位置与当前括号'('不匹配
if((i - 1 - dp[i - 1]) >= 0 && s.charAt(i - 1 - dp[i - 1]) == '(') {//查看【前一个位置下标-匹配数】之后的字符与当前括号')'是否匹配
dp[i] = dp[i - 1] + 2;//如果匹配,则在前一个位置匹配数的情况下+2,即加上刚与当前')'匹配的左右括号数量
if(i - 2 - dp[i - 1] >= 0) {//加上与')'匹配的'('前一个位置的dp匹配长度
dp[i] += dp[i - 2 - dp[i - 1]];
}
}
}
}
res = Math.max(res, dp[i]);
}
return res;
}

32.Longest Valid Parentheses---dp的更多相关文章

  1. 刷题32. Longest Valid Parentheses

    一.题目说明 题目是32. Longest Valid Parentheses,求最大匹配的括号长度.题目的难度是Hard 二.我的做题方法 简单理解了一下,用栈就可以实现.实际上是我考虑简单了,经过 ...

  2. [Leetcode][Python]32: Longest Valid Parentheses

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 32: Longest Valid Parentheseshttps://oj ...

  3. leetcode 20. Valid Parentheses 、32. Longest Valid Parentheses 、

    20. Valid Parentheses 错误解法: "[])"就会报错,没考虑到出现')'.']'.'}'时,stack为空的情况,这种情况也无法匹配 class Soluti ...

  4. 32. Longest Valid Parentheses (Stack; DP)

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  5. [LeetCode] 32. Longest Valid Parentheses 最长有效括号

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  6. 32. Longest Valid Parentheses

    题目: Given a string containing just the characters '(' and ')', find the length of the longest valid ...

  7. leetcode解题报告 32. Longest Valid Parentheses 用stack的解法

    第一道被我AC的hard题!菜鸡难免激动一下,不要鄙视.. Given a string containing just the characters '(' and ')', find the le ...

  8. 32. Longest Valid Parentheses (JAVA)

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  9. leetcode 32. Longest Valid Parentheses

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  10. Java [leetcode 32]Longest Valid Parentheses

    题目描述: Given a string containing just the characters '(' and ')', find the length of the longest vali ...

随机推荐

  1. codeforces 1027 E. Inverse coloring (DP)

    E. Inverse Coloring time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. BZOJ4923 K小值查询(splay)

    容易想到建一棵平衡树,修改时打上标记即可.但是修改会导致平衡树结构被破坏.注意到实际上只有[k+1,2k)这一部分数在平衡树中的位置会被改变,所以对这一部分暴力修改,因为每次都会使其至少减小一半,复杂 ...

  3. Jsp遍历后台传过来的List

    1:使用jstl标签 (可以和自定义标签配合使用) 首先引用jstl标签 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" ...

  4. 【BZOJ4817】树点涂色(LCT,线段树,树链剖分)

    [BZOJ4817]树点涂色(LCT,线段树,树链剖分) 题面 BZOJ Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义 ...

  5. (转)Xsl 的Webshell(aspx)版本

    关于使用xsl的webshell以前已经有人发过了,比如aspx的一个webshell如下: <%@ Page Language="C#" Debug="true& ...

  6. 常用Actoin算子 与 内存管理 、共享变量、内存机制

    一.常用Actoin算子 (reduce .collect .count .take .saveAsTextFile . countByKey .foreach ) collect:从集群中将所有的计 ...

  7. 解题:SCOI 2014 方伯伯运椰子

    题面 很有趣的一道题,看起来是个神奇网络流,其实我们只要知道网络的一些性质就可以做这道题了 因为题目要求流量守恒,所以我们其实是在网络中搬运流量,最终使得总费用减小,具体来说我们可以直接把这种“搬运” ...

  8. 【agc004F】Namori

    Portal -->agc004F Solution  好神仙的转化qwq ​  首先我们可以先考虑\(m=n-1\)的情况下,也就是树的情况下要怎么做  我们可以将这个问题转化一下:我们对这颗 ...

  9. 解析C#彩色图像灰度化算法的实现代码详解

    http://www.jb51.net/article/37067.htm public static Bitmap MakeGrayscale(Bitmap original)        {   ...

  10. (转)select、poll、epoll之间的区别

    本文来自:https://www.cnblogs.com/aspirant/p/9166944.html (1)select==>时间复杂度O(n) 它仅仅知道了,有I/O事件发生了,却并不知道 ...