算法描述
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可 行解。
每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。
若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。
如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。
这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。
1:题目描述
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度
2:测试案例
测试案例1:
输入:s = “(()”
输出:2
解释:最长有效括号子串是 “()”
测试案例2:
输入:s = “)()())”
输出:4
解释:最长有效括号子串是 “()()”
提示:
0 <= s.length <= 3 * 10^4
s[i] 为 ‘(’ 或 ‘)’
3:解题思路
当前,自己对于DP算法的理解:求解一个大问题,分解成子问题进行求解,子问题求解出来后,其答案不会被后面的问题干扰,对该子问题不需要再次进行计算,直接取计算好的结果即可。
4:代码解析
class Solution {
public:
int longestValidParentheses(string s)
{
//动态规划解答
int maxlen = 0;
const int len = s.size();
vector<int> dp(len, 0);//声明存储结果的DP表,并初始化为0
for (int i = 1; i < len; ++i)
{
if (s[i] == ')')
{
if (s[i - 1] == '(')
dp[i] = (i - 2>=0?dp[i - 2]:0) + 2;
else
if (i - dp[i - 1] > 0 && s[i - dp[i - 1] - 1] == '(') {
dp[i] = dp[i - 1] + ((i - dp[i - 1]) > 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
}
maxlen = max(maxlen, dp[i]);
};
};
return maxlen;
}
};
5:题目总结
本篇文章主要记录动态规划,后续会再次进行修改,由于自己对动态规划的了解还是比较浅,使用难度较大,思维过于灵敏。