最先看到这一题,直觉的解法就是len从1到s1.size()-1,递归调用比較s1和s2长度为len的子串是否相等。以及剩余部分是否相等。

将s1分成s1[len + rest],分别比較s2[len + rest]和s2[rest + len]

代码例如以下:

    bool isScramble(string s1, string s2) {
return find(s1, s2);
} bool find(string s1, string s2) {
if (s1.compare(s2) == 0) return true;
for (int i = 1; i < s1.size(); i++)
{
if (find(s1.substr(0, i), s2.substr(0,i)) && find(s1.substr(i), s2.substr(i)))
return true;
if (find(s1.substr(0, i), s2.substr(s2.size() - i)) && find(s1.substr(i), s2.substr(0, s2.size() - i)))
return true;
}
return false;
}

是一个TLE的算法

改进点1:在find中查看s1和s2是否字母同样,假设不同。返回false

代码例如以下:

    bool isScramble(string s1, string s2) {
return find(s1, s2);
} bool find(string s1, string s2) {
if (!haveSameChar(s1, s2)) return false;
if (s1.compare(s2) == 0) return true;
for (int i = 1; i < s1.size(); i++)
{
if (find(s1.substr(0, i), s2.substr(0,i)) && find(s1.substr(i), s2.substr(i)))
return true;
if (find(s1.substr(0, i), s2.substr(s2.size() - i)) && find(s1.substr(i), s2.substr(0, s2.size() - i)))
return true;
}
return false;
} bool haveSameChar(string& s1, string& s2)
{
int chars[26] = {0};
for (int i = 0; i < s1.size(); i++)
{
chars[s1[i] - 'a'] ++;
}
for (int i = 0; i < s2.size(); i++)
{
if (chars[s2[i] - 'a'] == 0) return false;
chars[s2[i] - 'a'] --;
}
return true;
}

改进点2:存储状态,将问题转换为三维DP

dp(i, j, l):s1[i...i+l]和s2[j...j+l]是否满足要求

dp(i, j, l) = dp(i, j, k) && dp(i + k, j + k, l - k) || dp(i, j + l - k, k) && dp(i + k, j, l - k)

    vector<vector<vector<int>>> dp;
bool isScramble(string s1, string s2) {
int size = s1.size();
dp = vector<vector<vector<int>> > (size, vector<vector<int>>(size, vector<int>(size + 1)));
return find(s1, s2, 0, 0, size);
} bool find(string & s1, string & s2, int l1, int l2, int length)
{
if (dp[l1][l2][length] != 0)
return dp[l1][l2][length] == 1;
dp[l1][l2][length] = -1;
if (length == 1)
dp[l1][l2][length] = ((s1[l1] == s2[l2]) ? 1 : -1);
for (int len = 1; len < length; len++)
{
if (find(s1, s2, l1, l2, len) && find(s1, s2, l1 + len, l2 + len, length - len))
{
dp[l1][l2][length] = 1;
break;
}
if (find(s1, s2, l1, l2 + length - len, len) && find(s1, s2, l1 + len, l2, length - len))
{
dp[l1][l2][length] = 1;
break;
}
}
return dp[l1][l2][length] == 1;
}

最新文章

  1. NDK开发_笔记0
  2. tcpdf最新版 6.2版
  3. ElasticSearch学习-centos下安装
  4. [部署]MVC4.0+EF5.0+ODT+ORACLE相关注意事项
  5. 编程工具系列之二------使用GDB的源代码查看功能
  6. java课程三课堂例子验证
  7. Linux下安装Android Studio(ubuntu)
  8. 实现iOS项目一款用swift实现的应用top源码
  9. 【POJ2094】【差分序列】Angry Teacher
  10. chmod -R o+rX /data
  11. HDU_2029——回文串的判断
  12. Sed简介 (转)
  13. Linux/UNIX数据文件和信息系统
  14. Ubuntu 发行版的 Linux 操作系统
  15. java.lang.OutOfMemoryError 解决程序启动内存溢出问题
  16. CentOS上安装MongoDB速记
  17. 虚拟机上的Ubuntu 文件系统成为只读模式的解决办法
  18. vue使用动态渲染v-model输入框无法输入内容
  19. webpack学习笔记--按需加载
  20. python进阶之 线程编程

热门文章

  1. erlang四大behaviour之一gen_server(转载)
  2. 微信中调起qq
  3. c# 获取Excel内容的分析
  4. php-fpm nginx 使用 curl 请求 https 出现 502 错误
  5. Java 中 byte 类型初始化问题
  6. Android开发人员必须掌握的10 个开发工具+应该深入学习的10个开源应用项目
  7. Hourrank 21 Tree Isomorphism 树hash
  8. c# @符号后面对 双引号转义
  9. C++获取系统时间方法(毫秒级)
  10. java中Comparator的用法 -- 实现集合和数组排序