leetcode:87. Scramble String

仅一步之遥就自己做出这道hard了:(
首先自己观察对于每个子问题都是一样的逻辑,所以适合用递归:
class Solution {
public:
bool isScramble(string s1, string s2) {
int sz1 = s1.size(), sz2 = s2.size();
if (sz1 != sz2)
return false;
return helper(s1, s2, 0, sz1-1, 0, sz2-1);
}
private:
bool helper(string& s1, string& s2, int l1, int r1, int l2, int r2) {
if (l1 == r1) {
if (s1[l1] == s2[l2])
return true;
else
return false;
}
for (int i = 1; i <= (r1 - l1); ++i) {
if (helper(s1, s2, l1, l1+i-1, l2, l2+i-1) && helper(s1, s2, l1+i, r1, l2+i, r2))
return true;
if (helper(s1, s2, l1, l1+i-1, r2-i+1, r2) && helper(s1, s2, l1+i, r1, l2, r2-i))
return true;
}
return false;
}
};
结果超时。
然后看了评论区,才发现忘了把中间结果保存:
class Solution {
public:
bool isScramble(string s1, string s2) {
int sz1 = s1.size(), sz2 = s2.size();
if (sz1 != sz2)
return false;
return helper(s1, s2, 0, sz1-1, 0, sz2-1);
}
private:
map<pair<pair<int, int>, pair<int, int>>, bool> m;//unordered_map不能用,需要自己提供hash函数。
bool helper(string& s1, string& s2, int l1, int r1, int l2, int r2) {
if (l1 == r1) {
if (s1[l1] == s2[l2])
return true;
else
return false;
}
auto key = make_pair(make_pair(l1, r1), make_pair(l2, r2));
if (m.find(key) != m.end())
return m[key];
for (int i = 1; i <= (r1 - l1); ++i) {
if (helper(s1, s2, l1, l1+i-1, l2, l2+i-1) && helper(s1, s2, l1+i, r1, l2+i, r2) ||
helper(s1, s2, l1, l1+i-1, r2-i+1, r2) && helper(s1, s2, l1+i, r1, l2, r2-i)) {
m[key] = true;
return true;
}
}
m[key] = false;
return false;
}
};
//1.没有想到对中间结果进行缓存,是一大失误。
//2.从顶向下的编码确实更加符合思考的逻辑。
DP的核心思想是保存子问题的解,不用重复解答。这里忘记了这一点,导致没有pass
这里的状态是:对于s1[l1:r1]和s2[l2:r2]来说,是不是scramble的?
这题其实就是top-down+memo,只是一开始没想到这一点,忘了memo
浙公网安备 33010602011771号