32.Longest Valid Parentheses---dp
题目链接: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的更多相关文章
- 刷题32. Longest Valid Parentheses
一.题目说明 题目是32. Longest Valid Parentheses,求最大匹配的括号长度.题目的难度是Hard 二.我的做题方法 简单理解了一下,用栈就可以实现.实际上是我考虑简单了,经过 ...
- [Leetcode][Python]32: Longest Valid Parentheses
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 32: Longest Valid Parentheseshttps://oj ...
- leetcode 20. Valid Parentheses 、32. Longest Valid Parentheses 、
20. Valid Parentheses 错误解法: "[])"就会报错,没考虑到出现')'.']'.'}'时,stack为空的情况,这种情况也无法匹配 class Soluti ...
- 32. Longest Valid Parentheses (Stack; DP)
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- [LeetCode] 32. 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解题报告 32. Longest Valid Parentheses 用stack的解法
第一道被我AC的hard题!菜鸡难免激动一下,不要鄙视.. Given a string containing just the characters '(' and ')', find the le ...
- 32. Longest Valid Parentheses (JAVA)
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- leetcode 32. Longest Valid Parentheses
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- Java [leetcode 32]Longest Valid Parentheses
题目描述: Given a string containing just the characters '(' and ')', find the length of the longest vali ...
随机推荐
- 【bzoj2600】[Ioi2011]ricehub 双指针法
题目描述 给出数轴上坐标从小到大的 $R$ 个点,坐标范围在 $1\sim L$ 之间.选出一段连续的点,满足:存在一个点,使得所有选出的点到其距离和不超过 $B$ .求最多能够选出多少点. $R\l ...
- 洛谷 P2421 A-B数对(增强版)
题目描述 给出N 个从小到大排好序的整数,一个差值C,要求在这N个整数中找两个数A 和B,使得A-B=C,问这样的方案有多少种? 例如:N=5,C=2,5 个整数是:2 2 4 8 10.答案是3.具 ...
- macvtap介绍
macvtap介绍 传统的linux网络虚拟化技术采用的是tap+bridge方式,将虚拟机连接到虚拟的tap网卡,然后将tap网卡加入到bridge.bridge相当于用软件实现的交换机,这种解决方 ...
- py2exe使用总结
假如你用python写了个小程序,想给别人用或者给别人演示,但他电脑里没装python.wxpython等,这时候你可以试试py2exe,它是一个将python脚本转换成windows上的可执行程序( ...
- 基于注解的spring mvc 中使用 ajax json 的model
在 Spring mvc3中,响应.接受 JSON都十分方便. 使用注解@ResponseBody可以将结果(一个包含字符串和JavaBean的Map),转换成JSON. 使用 @RequestBod ...
- 【BZOJ2460】元素(贪心,线性基)
[BZOJ2460]元素(贪心,线性基) 题面 BZOJ Description 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔 法矿石炼制法杖的技术.那时人们就认识到 ...
- Win10如何搭建FTP服务器以实现快速传输文件
原文链接地址:http://blog.csdn.net/bai_langtao/article/details/77751447 Win10如何搭建FTP服务器以实现快速传输文件?相信大家在工作或生活 ...
- 【原创】【2】rich editor系列教程。了解document.execommand操作,保存丢失的range,实时反馈样式给工具栏
[原创][2]rich editor系列教程.了解document.execommand操作,保存丢失的range,实时反馈样式给工具栏 索引目录:http://www.cnblogs.com/hen ...
- bzoj3251: 树上三角形(思维题)
神tmWA了8发调了20min才发现输出没回车T T... 首先考虑一段什么样的序列才会是N... 显然最长的形式就是斐波那契,前两数之和等于第三数之和,这样就无法组成三角形并且序列最长.可以发现在i ...
- springboot缓存开发
前言:缓存在开发中是一个必不可少的优化点,近期在公司的项目重构中,关于缓存优化了很多点,比如在加载一些数据比较多的场景中,会大量使用缓存机制提高接口响应速度,简介提升用户体验.关于缓存,很多人对它都是 ...