LeetCode_32
题目描述:
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"
本题还有一个前置题目,详细内容可以点击此链接跳转 LeetCode_20,解决方案可以查看我的这篇CSDN博客 Li-Richard
稍微有点算法基础的同学看到本题时,脑海里第一个想法应该是使用DP来解决该问题,因为觉得应该可以用之前的结论推出后面一个结论,所以我们直接来讨论如何使用DP方法
比如一个字符串")()())",我们先写出对该字符串中以每一个字符为结尾的字符串的最长有效括号的长度
|字符串的每个字符| ) | ( | ) | ( | ) | ) |
| ------------ | ------------ | ------------ | ------------ | ------------ | ------------ |
|字符串每个字符的位置| 0 | 1 | 2 | 3 | 4 | 5 |
|以相应字符结尾的最长有效括号的长度| 0 | 0 | 2 | 0 | 4 | 0 | |
(以下以len(i)表示i位置的最大有效括号字符串的长度)
在计算的过程中,如果位置i的字符为'(',则len(i)肯定为0(好好想想为什么)
此时你正在计算len(4),它是')',此时你首先应该看len(3),找到3-len(3)位置的字符看它是否为'(',若是则len(4)=len(3)+2
等等,我们好像算的不对,如果按照我们上面的算法len(4)应该等于2但实际情况应该等于4,我们好像忽略了什么。
再回到上面的分析,我们找到了3-len(3)的位置后,再往前看,len(3-len(3)-1)(意思为3-len(3)位置之前的字符的len)的值不为零,所以我们应该还要叫上这个位置的len,所以len(4)=len(3)+2+len(3-len(3)-1)(写程序时要注意数组下标不要越界)
所以初步的动态转移方程可以归纳为:
dp[i]=dp[i-1]+2+dp[i-1-dp[i-1]-1] (这只是初步的dp方程,没有判断s[i]和s[i-1-dp[i-1]]的情况)
代码如下:
int longestValidParentheses(string s)
{
if (s==""||s.length()==0||s.length()==1)
{
return 0;
}
int len = s.length();
vector<int>dp(len,0);
for (int i = 0; i < len; i++)
{
if (i==0)
{
dp[i] = 0;
}
else
{
if (s.at(i) == '(')
{
dp[i] = 0;
}
else
{
//重点在这
int pre = i - 1 - dp[i - 1];
if (pre >= 0 && s[pre] == '(')
dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0);
}
}
}
sort(dp.begin(), dp.end());
return dp[len - 1];
}

LeetCode_32的更多相关文章
随机推荐
- 验证码生成器(在TImage.Canvas上写字,很好看)
生成验证码的方式有很多种,如下则是比较简单的实现,且运用了正余弦曲线来扭曲验证码字符. unit AuthenticodeGenerate; interface uses SysUtils, Wind ...
- js一道面试题
题目是这样的,按照以下函数的结果写一个sub()方法: sub(1)(2)(3);/*return 6*/ sub(4)(3)(3);/*return 10*/ 我的山寨做法: function su ...
- Google三驾马车:GFS、MapReduce和Bigtable
谈到分布式系统,就不得不提Google的三驾马车:Google fs[1],Mapreduce[2],Bigtable[3]. 虽然Google没有公布这三个产品的源码,但是他发布了这三个产品的详细设 ...
- 怎么看待php 面向对象思想
面向对象的程序设计思路是现代程序设计由面向过程演变面向对象的必然趋势,所以面向对象的而设计思路必然有它不同的时代意义,必然有着不同面向过程的不同历史使命,而php 5以后成功添加面向对象的设计思路其实 ...
- python中的while循环,格式化输出,运算符,编码
一.while循环 1.1语法 while 条件: 代码块(循环体) else: 当上面的条件为假的的时候,才会执行. 执行顺序:先判断条件是否为真,如果是真的,执行循环体,再次判断条件,直到条件不成 ...
- Java集合 ArrayList原理及使用
ArrayList是集合的一种实现,实现了接口List,List接口继承了Collection接口.Collection是所有集合类的父类.ArrayList使用非常广泛,不论是数据库表查询,exce ...
- sql一关联多查询时否定筛选出现的问题的解决
问题:一方关联多方查询时执行否定筛选,结果包含未通过筛选的项. 我们规定一方为父,多方为子,我们希望子未通过筛选时,结果也不出现对应的父. 查询部门及部门下的所有员工. SELECT * FROM d ...
- 使用Hibernate连接Oracle 无法识别生成的SQL问题
问题: 在JAVA工程中,数据库使用的是OracleXE(Oracle10g Express Edition). 使用hibernate.reveng.xml创建了实体类及其DAO类,如: tt.my ...
- __file__、__name__、__dict__方法整理
本文主要介绍__file__.__name__.__dict__三个方法的作用. #01 __file__:打印当前文件的位置. # import os # print(__file__) # 在py ...
- Qemu搭建ARM vexpress开发环境(三)----NFS网络根文件系统
Qemu搭建ARM vexpress开发环境(三)----NFS网络根文件系统 标签(空格分隔): Qemu ARM Linux 经过上一篇<Qemu搭建ARM vexpress开发环境(二)- ...