第一道被我AC的hard题!菜鸡难免激动一下,不要鄙视..

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.

题目大意:给出一个字符串,给出左右括号完全匹配的最大子串长度。

最开始想着套动态规划,当s[i]..s[j]是完全匹配的,dp[i][j] = j - i +1. 否则dp[i][j] = 0;

然后对各个长度判断。。太笨了。O(n2)的复杂度,超时是必然的,还有bug。

忍不住点开discuss,看了一眼标题,人家是O(n)复杂度,一遍过。惊叹!用的stack。我怎么这么笨呢。。括号匹配、表达式求值就用过stack啊。

懒得琢磨答案的代码,继续自己想。感觉这个题有戏。

在纸上画个字符串模拟,怎么用好一个栈(或者两个栈)。

直接写最后的想法了。中间过程全靠灵感。。

遇到(就压栈。

遇到),取出一个元素。如果取出的是(,匹配了,把()变成数字2,压进去。

如果取出的是数字,继续取,把取出的所有连续数字变成一个长度,直到pop出来的不是数字(字符或者空)。

把最近的左右括号变成2,把相邻的2变成4,把相邻的数字变成更大的和。

然后进行匹配的时候,栈里的数字当做透明的。先全部取出数字,再判断左右括号的匹配。

不管是否匹配,最后要把数字和符号原路压回去。

用字符串演示一下过程:

i = 0和1,左括号入栈

i = 2,s[1]出栈,匹配。变成2压入栈。

i = 3和4, s[3]、s[4]入栈

i = 5,s[4]出栈,变成2压进去。

i = 6,把2取出来,把s[3]取出来,s[3]和s[6]匹配变成2。加上取出来的2,变成4,压进去。

....

最后计算栈里面连续的、不被字符隔断的数字的总和的最大值。

这里遇到一个问题,就是数字 和 () 符号怎么区分。我用了负数来表示。中间出了两次bug,就是有的地方依然用char表示的,负数肯定不能用char了。。

上代码了。。用的C语言,自己写的栈。笨啊   赶紧把STL搞起来!

虽然代码很长,但是好像可读性强一点? 呵呵

struct stack{
int *data;    //存放 括号或者已经匹配的个数(负值)
int n;      //size
int top;
}; typedef struct stack* Stack; Stack new_stack(int n)
{
Stack hd = (Stack)malloc(sizeof(struct stack));
hd->data = (int*)malloc(n*sizeof(int));
hd->top = -;
hd->n = n;
return hd;
} void del_stack(Stack hd)
{
if(hd)
{
if(hd->data) free(hd->data);
free(hd);
}
}
bool is_full(Stack hd)
{
return hd->top == hd->n - ;
} void push(Stack hd, int ch)
{
if( is_full(hd) )
{
int *tmp = (int*)malloc(sizeof(int)*(hd->n + ));
memcpy(tmp,hd->data,hd->n*sizeof(int));
free(hd->data);
hd->data = tmp;
hd->n += ;
} hd->data[++hd->top] = ch;
} int pop(Stack hd)        // 返回值为0表示空栈。
{
if(hd->top < )
return ;
return hd->data[hd->top--];
}
int top(Stack hd)        // 返回值为0表示空栈。
{
if(hd->top < )
return ; return hd->data[hd->top];
} int longestValidParentheses(char* s) {
Stack hd ;
int i,j,k,n = strlen(s);
int cnt,ans;
if(s == NULL || n == )
{
return ;
} hd = new_stack();
for(i=; i<n; i++)
{
if( s[i] == '(' ) // 左侧括号放入
{
push(hd,s[i]);
}
else // 遇到右括号开始处理
{
int ch = pop(hd); // 有4种: '(' ')' 0 负值
if(ch == '(')
{
push(hd,-); //说明匹配了,放进去一个-2代替()
}
else if(ch == ) //表示已经空了。无法匹配了。把)放进去作为间隔
{
push(hd,s[i]);
}
else if(ch < ) //如果之前有匹配好的,
{
while(top(hd)<)
{
ch += pop(hd); //拿出来匹配好的,归并成一个数
}
if(top(hd) == '(' ) //如果是远程匹配,又多了一个2
{
ch += -;
pop(hd);
push(hd,ch);
}
else //如果确定不匹配了,把计算好的匹配数放进去,再把s[i]放进去作为间隔
{
push(hd,ch);
push(hd,s[i]);
}
}
else // 总之是不匹配了
{
push(hd,s[i]);
}
}
}
//计算栈中连续负数的最大值。
ans = cnt = ;
while(hd->top >= )
{
int ch = pop(hd);
if(ch < )
{
cnt -= ch;
if(cnt > ans) ans = cnt;
}
else
{
cnt = ;
}
}
del_stack(hd); return ans;
}

leetcode解题报告 32. Longest Valid Parentheses 用stack的解法的更多相关文章

  1. leetcode解题报告 32. Longest Valid Parentheses 动态规划DP解

    dp[i]表示以s[i]结尾的完全匹配的最大字符串的长度. dp[] = ; ; 开始递推 s[i] = ')' 的情况 先想到了两种情况: 1.s[i-1] = '(' 相邻匹配 这种情况下,dp ...

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

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

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

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

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

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

  5. 刷题32. Longest Valid Parentheses

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

  6. 【一天一道LeetCode】#32. Longest Valid Parentheses

    一天一道LeetCode系列 (一)题目 Given a string containing just the characters '(' and ')', find the length of t ...

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

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

  8. Java [leetcode 32]Longest Valid Parentheses

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

  9. leetcode 32. Longest Valid Parentheses

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

随机推荐

  1. 服务注册发现consul之四: 分布式锁之四:基于Consul的KV存储和分布式信号量实现分布式锁

    一.基于key/value实现 我们在构建分布式系统的时候,经常需要控制对共享资源的互斥访问.这个时候我们就涉及到分布式锁(也称为全局锁)的实现,基于目前的各种工具,我们已经有了大量的实现方式,比如: ...

  2. 《Java 程序设计》课堂实践项目 课后学习总结

    <Java 程序设计>课堂实践项目 课后学习总结 String类的使用(sort) 目录 Linux命令(sort) 课堂实践 课后思考 学习老师的代码之后的思考:int与Integer ...

  3. 04 bash程序的基本特性

    我们知道Linux系统有两种操作方式,一种为GUI的图形界面化管理方式,其中图形程序常见的有Gnome.KDE.xfce:另一种管理方式就是就是GLI的命令行管理方式,而命令行的管理方式就是通过she ...

  4. Apached+resin服务搭建

    一.前言 Resin是CAUCHO公司的产品,是一个非常流行的支持servlets 和jsp的引擎,速度非常快.对servlet和JSP提供了良好的支持,性能也比较优良,resin自身采用JAVA语言 ...

  5. Android最新版支付宝支付集成

    上次集成支付宝支付已经很久了,今天写东西用到了支付宝支付,就大致写一下流程: 去蚂蚁金服下载最新版的Android&IOS端SDK 全部文档 -- 资源下载 -- App支付客户端 下载后解压 ...

  6. ASCII、Unicode和UTF-8

    转自廖雪峰的官方网站:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00138 ...

  7. nodejs运行的两种方式<小记>

    在mac上: 1.方式一:使用IDE运行 配置需要运行的js文件: 配置并运行 ①配置运行的js文件和运行的文件不一致时会导致报错.如图备注 ②当运行另一个文件提示端口8080被占用 ,需要改为其他端 ...

  8. WPF Stake

    WPF中的StackPanel.WrapPanel.DockPanel 转:http://blog.sina.com.cn/s/blog_6c81891701017a34.html StackPane ...

  9. javascript中的未定义和未声明

    我们在项目中,经常会定义一些变量(很多时候,定义过多的全局变量),当我们调用这些变量的时候,就会发生各种各样的突发状况. 看一个示例: var a; typeof a; typeof b; 很简单的一 ...

  10. 傅立叶变换系列(五)快速傅立叶变换(FFT)

    说明: 傅里叶级数.傅里叶变换.离散傅里叶变换.短时傅里叶变换...这些理解和应用都非常难,网上的文章有两个极端:“Esay”  Or  “Boring”!如果单独看一两篇文章就弄懂傅里叶,那说明你真 ...