Scramble String -- LeetCode
原题链接: http://oj.leetcode.com/problems/scramble-string/
这道题看起来是比較复杂的,假设用brute force,每次做分割,然后递归求解,是一个非多项式的复杂度,一般来说这不是面试官想要的答案。
这事实上是一道三维动态规划的题目,我们提出维护量res[i][j][n],当中i是s1的起始字符,j是s2的起始字符,而n是当前的字符串长度,res[i][j][len]表示的是以i和j分别为s1和s2起点的长度为len的字符串是不是互为scramble。
有了维护量我们接下来看看递推式,也就是怎么依据历史信息来得到res[i][j][len]。推断这个是不是满足,事实上我们首先是把当前s1[i...i+len-1]字符串劈一刀分成两部分,然后分两种情况:第一种是左边和s2[j...j+len-1]左边部分是不是scramble,以及右边和s2[j...j+len-1]右边部分是不是scramble;另外一种情况是左边和s2[j...j+len-1]右边部分是不是scramble,以及右边和s2[j...j+len-1]左边部分是不是scramble。假设以上两种情况有一种成立,说明s1[i...i+len-1]和s2[j...j+len-1]是scramble的。而对于推断这些左右部分是不是scramble我们是有历史信息的,由于长度小于n的全部情况我们都在前面求解过了(也就是长度是最外层循环)。
上面说的是劈一刀的情况,对于s1[i...i+len-1]我们有len-1种劈法,在这些劈法中仅仅要有一种成立,那么两个串就是scramble的。
总结起来递推式是res[i][j][len] = || (res[i][j][k]&&res[i+k][j+k][len-k] || res[i][j+len-k][k]&&res[i+k][j][len-k]) 对于全部1<=k<len,也就是对于全部len-1种劈法的结果求或运算。由于信息都是计算过的,对于每种劈法仅仅须要常量操作就可以完毕,因此求解递推式是须要O(len)(由于len-1种劈法)。
如此总时间复杂度由于是三维动态规划,须要三层循环,加上每一步须要线行时间求解递推式,所以是O(n^4)。尽管已经比較高了,可是至少不是指数量级的,动态规划还是有非常大有事的,空间复杂度是O(n^3)。代码例如以下:
public boolean isScramble(String s1, String s2) {
if(s1==null || s2==null || s1.length()!=s2.length())
return false;
if(s1.length()==0)
return true;
boolean[][][] res = new boolean[s1.length()][s2.length()][s1.length()+1];
for(int i=0;i<s1.length();i++)
{
for(int j=0;j<s2.length();j++)
{
res[i][j][1] = s1.charAt(i)==s2.charAt(j);
}
}
for(int len=2;len<=s1.length();len++)
{
for(int i=0;i<s1.length()-len+1;i++)
{
for(int j=0;j<s2.length()-len+1;j++)
{
for(int k=1;k<len;k++)
{
res[i][j][len] |= res[i][j][k]&&res[i+k][j+k][len-k] || res[i][j+len-k][k]&&res[i+k][j][len-k];
}
}
}
}
return res[0][0][s1.length()];
}
个人认为这是LeetCode中最难的动态规划的题目了,要进行一次三维动态规划,对于维护量的含义也比較讲究。有朋友会讨论这个维护量是怎么提出来的,我自己也没什么绝对的方法,还是熟能生巧,靠“感觉”,做的题目多了就自然来了,这个做高中数学题有点类似哈,辅助线是靠“灵感”的哈。面试中假设遇到就是top难度的了,只是即使如此,仅仅要思路清晰,还是能够记住的。假设没做过,个人认为比較难当场想出来,只是算法大牛就另说了,这样的题非常常常出如今编程比赛中,ACM高手还是不在话下的哈。
Scramble String -- LeetCode的更多相关文章
- Scramble String leetcode java
题目: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty subs ...
- 【一天一道LeetCode】#87. Scramble String
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- Leetcode:Scramble String 解题报告
Scramble String Given a string s1, we may represent it as a binary tree by partitioning it to two no ...
- 【leetcode】Scramble String
Scramble String Given a string s1, we may represent it as a binary tree by partitioning it to two no ...
- 【LeetCode练习题】Scramble String
Scramble String Given a string s1, we may represent it as a binary tree by partitioning it to two no ...
- [leetcode]87. Scramble String字符串树形颠倒匹配
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...
- [LeetCode] Scramble String -- 三维动态规划的范例
(Version 0.0) 作为一个小弱,这个题目是我第一次碰到三维的动态规划.在自己做的时候意识到了所谓的scramble实际上有两种可能的类型,一类是在较低层的节点进行的两个子节点的对调,这样的情 ...
- [leetcode] 87. Scramble String (Hard)
题意: 判断两个字符串是否互为Scramble字符串,而互为Scramble字符串的定义: 字符串看作是父节点,从字符串某一处切开,生成的两个子串分别是父串的左右子树,再对切开生成的两个子串继续切开, ...
- [LintCode] Scramble String 爬行字符串
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...
随机推荐
- hdu 3389 阶梯博弈
题意:1-N带编号的盒子,当编号满足A>B && A非空 && (A + B) % 3 == 0 && (A + B) % 2 == 1则可以从A ...
- CCF CSP 201604-2 俄罗斯方块
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201604-2 俄罗斯方块 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游 ...
- Spark(一)Spark简介
一.官网介绍 1 什么是Spark 官网地址:http://spark.apache.org/ Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎.Spark是UC Berkel ...
- Java项目中classpath路径
1.src不是classpath, WEB-INF/classes.lib.resources才是classpath,WEB-INF/是资源目录, 客户端不能直接访问. 2.WEB-INF/class ...
- day6面向对象
面向对象介绍(http://www.cnblogs.com/alex3714/articles/5188179.htm) 世界万物,皆可分类 世界万物,皆为对象 只要是对象,就 ...
- 6-14 Inspector s Dilemma uva12118(欧拉道路)
题意:给出一个国家城市个数n 所需走过道路个数e 每条道路长t 该国家任意两个城市之间都存在唯一道路长t 要求 :找一条最短的路遍历所有所需走过的路 一开始以为是图的匹配 但是好 ...
- spring boot配置使用fastjson
一.前言 spring boot默认使用jackson来操作json数据,相比于jackson,fastjson更好用,功能也强大,所以这里记录一下在spring boot中配置使用fastjson的 ...
- 把对象转换成JSON形式的html代码
function formatJson(msg) { var rep = "~"; var jsonStr = JSON.stringify(msg, null, rep) var ...
- 《Android源码设计模式》----面向对象六大原则
1.单一职责原则 Single Respoonsibility Principle(SRP) --封装 2.开闭原则 Open Close Principle(OCP)--对扩展开放,对修改封闭 3. ...
- Python并发编程系列之多线程
1 引言 上一篇博文详细总结了Python进程的用法,这一篇博文来所以说Python中线程的用法.实际上,程序的运行都是以线程为基本单位的,每一个进程中都至少有一个线程(主线程),线程又可以创建子线程 ...