Interleaving String
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc",
s2 = "dbbca",
When s3 = "aadbbcbcac", return true.
When s3 = "aadbbbaccc", return false.
从开始看这道题目到最后Pass OJ,居然用了将近一个月,==!我实在是弱爆了。
做到只剩下五道题时候完完全全是“山重水复已无路”的绝境,之前遇到头痛的就扔下难的挑个相对简单的,有思路的,可是现在的情况是看哪个都是没思路。。。
其实这道题并不是“一看两眼黑”的题目,但想通过Time Limit实在是太难,==! 闷了整整三天,才在凌晨时分把这道题的DP思路闷好,然后起床开始重新写代码,最终在凌晨4:30的时候完成之前错误样本和各种小样本的测试,不过到图书馆重新OJ的时候仍然需要改动几次:==!
其实这道题最Straight forward的思路就是Recursion,但Recursion遇到String1, String2里有大量重复的字串的时候Running time就太长了,比如两串里都有一段abababab, abababab的时候,Recursion次数是以2的指数次方的形式开始增长的;
于是改成DP动态规划,一开始还以为要弄个3D的大型魔方,但想来想去那个计算时间也不短(当然要比2^n要快很多);
于是在纸上画“手动档”解题思路:
在string1为Row,以string2为col,建立一个2D的Matrix,然后把String3当做一条“绳子”从Matrix的最左上角开始铺,如果string3.charAt(i)和matrix左边界的字符相同,则绳子可以向下走,如果string3.charAt(i)和Matrix上边界的字符相同,则绳子可以往左铺(这个比喻不太好,但我情商较低的大脑想不出更好的比喻了) 请见下图:
文本文档里显示的是两组结果,两次输入相同的string1和string2,但输入不同的string3;
第一组结果是 string3可以一直铺到Matrix的右下角,这样就表示string3是可以被string1 and string2 reconstruct.
第二组结果可以看出来,string3在铺到aadbbb之后就没法继续走了,最后的四个字符没办法匹配。
另外一个非常有意思的现象是,如果用DP+Matrix在少量字符输入的时候,RunningTime仍然挺多的,但在大字串的时候居然也不慢;可是在用Recursion的时候,少量字符串时可以用“光速”来形容,但在大字串输入的时候就成了龟速。
完整的原代码证见GitHub:
Dynamic Programming with matrix:
Recursion:
https://github.com/breezedu/LeetCode2012/blob/master/InterleavingStringRecursion.java
其实我对Recursion这段非常满意,代码也相当简洁,就是running time久了点,==!