[Leetcode] 32.最长有效括号
时间:2019-09-13
本文章向大家介绍[Leetcode] 32.最长有效括号,主要包括[Leetcode] 32.最长有效括号使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
[Leetcode] 32.最长有效括号
关键词:DP,动态规划,动规。
最近在刷DP专栏的题目,这是其中一道题。
给定一个只包含 '('
和 ')'
的字符串,找出最长的包含有效括号的子串的长度。
Sample1
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
Sample2
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"
对于DP嘛,首先还是需要抽象出状态函数:
dp[i] 表示:以 S[i] 结尾的,最长有效括号串的长度。
然后是状态转移方程:
如果 s.len == 0 or s.len == 1,那么返回 0 .
否则:
if s[i]=='(' then dp[i]=0
if s[i]==')' then:
if s[i-1]='(' then dp[i] = dp[i-2] + 2 (数组下标是否越界,即 i>=2? )
if s[i-1]=')' then:
if s[i-dp[i-1]-1] == '(' then dp[i] = dp[i-dp[i-1]-2] + dp[i-1] + 2 (是否越界?)
if s[i-dp[i-1]-1] == ')' then dp[i] = 0
第一个 if
语句表示:形如 ....(
这样的字符串,是必然不合法的。
第二个 if
语句表示:形如 ....)
这样的字符串,这样我们需要考虑 s[i-1]
:
s[i-1]='('
: 字符串形如...()
,显然,下标对应如下:i-2 i-1 i x ( )
显然,
dp[i]
的值应当是dp[i-2] + 2
。s[i-1]=')
: 字符串形如...))
,显然,下标对应如下:? i-1 i x (... ) )
现考虑与
s[i-1]
匹配的 左括号的位置,s[i-1]=')'
,其合法的括号串长度是dp[i-1]
,那么'('
的位置应当是:i - 1 - (dp[i-1] - 1) = i - dp[i-1]
也就是说,
s[i] = )
匹配的左括号位置应当是:i - dp[i-1] - 1
.i-dp[i-1]-1 i-dp[i-1] i-1 i x ( ... ) )
如果
x = s[i-dp[i-1]-1] == )
,那么:dp[i] = dp[i-dp[i-1]-2] + dp[i-1] + 2
(因为 “ 没画出来的 ” 前面仍有可能是有效的括号串)但是如果
i-dp[i-1]-1
这个位置的符号不是(
呢?这就说明以s[i]
为结尾的括号传不是合法的,即:d[i] = 0
。完整代码:
需要特别注意数组下标越界的问题,一旦越界,说明前面不是一个有效的括号串。
/* DP解法: dp[i] 表示:以s[i]结尾的,最长有效子串 那么: if s[i]=='(' then dp[i] = 0 if s[i]==')': if (s[i-1]=='(') then dp[i] = dp[i-2]+2 if (s[i-1]==')') then dp[i] = dp[i-dp[i-1]-2] + dp[i-1] + 2 */ #include "leetcode.h" #include <stack> class Solution { public: int longestValidParentheses(string s) { int len = s.length(); if (len == 0 || len == 1) return 0; vector<int> dp(len, 0); for (int i = 1; i < len; i++) { if (s[i] == ')') { if (s[i - 1] == '(') { if (i >= 2) dp[i] = dp[i - 2] + 2; else dp[i] = 2; } else if (s[i - 1] == ')') { int midlen = dp[i - 1]; if (i >= (midlen + 1)) { char c = s[i - midlen - 1]; if (c == '(') dp[i] = dp[i - 1] + 2 + (i >= (midlen + 2) ? dp[i - midlen - 2] : 0); else dp[i] = 0; } else { dp[i] = 0; } } } } for (int x : dp) cout << x << ' '; cout << endl; int result = -1; for (int x : dp) result = max(result, x); return result; } }; int main() { string s[] = {"())", "(()", ")()())"}; Solution sol; for (int i = 0; i < 3; i++) cout << sol.longestValidParentheses(s[i]) << "\n" << endl; }
原文地址:https://www.cnblogs.com/sinkinben/p/11516742.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 有序链表转换二叉搜索树
- 128. 最长连续序列
- 【DB笔试面试859】在Oracle中,内核参数kernel.shmall、kernel.shmall等分别代表什么含义?
- Nginx配置SSL证书
- java_Object类、日期时间类、System类、包装类
- [周末往期回顾]UNDO_TABLESPACE参数
- WordPress固定链接后404解决方法
- [Oracle故障处理]记一次INST_DRTLD_MISMATCH导致的version count过多的问题
- 查表法实现十进制转化成其他进制
- ArrayList源码分析
- java_String类、StringBuilder类、Arrays类、Math类的使用
- 抽象类与接口
- java_static、final、super、this关键字的使用
- Lambda表达式
- java_字节流、字符流