【动态规划】LeetCode 32 最长有效括号-Medium

143 阅读1分钟

题目

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

输入: "(()"
输出: 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);
};

总结

在遇到动态规划问题时,需要冷静下来认真分析,慢慢画图分析,需要从自顶而下或者自底而上两种方式去分析问题,最好结合画图,从而找出状态转移方程。