题目
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"
动态规划四步走
1. 定义状态
2. 初始状态
3. 状态转移方程
4. 从dp[]中获取结果
具体到题目
定义状态
定义dp 数组,第 i 个元素表示以下标为i的字符结尾的最长有效子字符串的长度。
初始状态
dp[0] = 0
状态转移方程
if 第i个位置为"(" => dp[i] = 0
if 第i个位置为")" =>if i-1位置为"(" ,则 pd[i] = i - 2 > 0 ? dp[i - 2] + 2 : 2;
if i-1位置为")"
if list[i - dp[i - 1] - 1] === '('
dp[i] =i - dp[i - 1] - 2 >= 0
? dp[i - 1] + dp[i - dp[i - 1] - 2] + 2
: dp[i - 1] + 2
else dp[i] = 0
从dp[]中获取结果
dp[]中的最大值就是所求结果
完整代码
var longestValidParentheses = function (s) {
const list = s.split('');
const dp = [0];
for (let i = 1; i < list.length; i++) {
if (list[i] === '(') {
dp[i] = 0;
} else if (list[i] === ')') {
if (list[i - 1] === '(') {
dp[i] = i - 2 > 0 ? dp[i - 2] + 2 : 2;
} else {
if (list[i - dp[i - 1] - 1] === '(') {
dp[i] =
i - dp[i - 1] - 2 >= 0
? dp[i - 1] + dp[i - dp[i - 1] - 2] + 2
: dp[i - 1] + 2;
} else {
dp[i] = 0;
}
}
}
}
console.log(dp);
return Math.max(...dp);
};
总结
在遇到动态规划问题时,需要冷静下来认真分析,慢慢画图分析,需要从自顶而下或者自底而上两种方式去分析问题,最好结合画图,从而找出状态转移方程。