【发布时间】:2020-04-18 00:35:29
【问题描述】:
上下文:我正在尝试通过提出递归解决方案然后缓存子问题的结果来学习动态编程。
我一直在为this LeetCode 问题苦苦挣扎。
给定一个只包含三种类型字符的字符串:'(', ')' 和 '*',编写一个函数来检查这个字符串是否有效。我们通过以下规则定义字符串的有效性:
任何左括号'('必须有一个对应的右括号')'。 任何右括号 ')' 必须有一个对应的左括号 '('。 左括号 '(' 必须在相应的右括号 ')' 之前。 '*' 可以被视为单个右括号 ')' 或单个左括号 '(' 或空字符串。 空字符串也是有效的。
示例 1:
Input: "()", Output: True示例 2:
Input: "(*)", Output: True示例 3:
Input: "(*))", Output: True
我设法想出了一个似乎可行的递归解决方案。但是,我无法将其转换为 DP,我什至不明白我应该从哪里开始或应该缓存什么,即我看不到递归子树的结果对于不同的子问题是如何相同的.我知道existing DP solution。但我无法将它与我的递归相关联。甚至可以将此特定解决方案转换为 DP 吗?非常感谢您的建议。
这是我的代码:
class Solution {
public:
bool checkValidString(string s) {
stack<int> paren_stack;
int ind = 0;
return check_valid_rec(s, ind, paren_stack);
}
private:
bool check_valid_rec(string& s, int ind, stack<int> paren_stack) {
if (ind >= s.size())
return paren_stack.empty();
while (s[ind] != '*' && ind < s.size()) {
if (s[ind] == '(')
paren_stack.push('(');
else {
if (!paren_stack.empty() && paren_stack.top() == '(')
paren_stack.pop();
else return false;
}
ind++;
}
if (ind >= s.size())
return paren_stack.empty();
// if '*', there are three options
// 1. ignore '*'
bool ignore = check_valid_rec(s, ind + 1, paren_stack);
// 2. replace with '('
s[ind] = '(';
bool left_replace = check_valid_rec(s, ind, paren_stack);
// 3. replace with ')'
s[ind] = ')';
bool right_replace = check_valid_rec(s, ind, paren_stack);
if (ignore || left_replace || right_replace)
return true;
else
return false;
}
};
【问题讨论】:
标签: c++ recursion dynamic-programming