
scramble(字符串s) 算法:
s长度为1时结束。
s可以拆分成2部分x和y,s=x+y,
这两部分可以交换,也可以不交换,即 s = x+y 或 s = y+x.
上面scramble还会递归作用于x 和 y.
给出相同长度的字符串s1, s2, 问s2是否可通过scramble(s1)获得。
思路:
假设s1和s2的长度是n.
在scramble算法中,第1,字符串可以拆分成两部分,
那么可以拆分的点可以在任意下标处,
所以需要遍历s1的所有下标。
假设遍历下标为 i 时,s 拆分成 0 ~ i 和 i+1 ~ n-1两段。所以 i : 0 ~ n-2 (不是n-1 !)
第2,拆分的两部分 可交换可不交换。
假设在 i 处把s1分成两部分: s1[0 ~ i] 和 s1[i+1 ~ n-1] ,
如果不交换,需要进一步scramble s1[0 ~ i] 和 s2[0 ~ i], s1[i+1 ~ n-1] 和 s2[i+1 ~ n-1].
如果交换,需要进一步scramble s1[0 ~ i] 和 s2[i ~ n-1], s1[i+1 ~ n-1] 和 s2[0 ~ i-1].
同时,我们观察到,
s1能scramble成s2的前提是 它们的字母必须是一样的(不管顺序)。
因为scramble只负责拆分和交换,并不会改变字母,
如果字母不一样,则s1 scamble不成s2的.
所以可以用一个长度为26的数组统计每个字母出现的次数,
因为涉及到交换和不交换,
所以分别用一个cnt统计s1[0 ~ i]的字母,
cntF统计s2[0 ~ i]的字母,cntB统计s2[i+1 ~ n-1]的字母。
字母个数相同时,再进行scamble算法。
两个字符串相等时结束。
已经判断过的,用一个map保存起来,再遇到同样的s1和s2, 直接取结果。
注意s必须是拆分成2部分,因此 i < n-1, 而不是 i < n,如果 i = n-1, 会相当于只拆分成一部分(即s1本身,会陷入无限循环)。
class Solution {
HashMap<String, Boolean> map = new HashMap<>();
public boolean isScramble(String s1, String s2) {
String s = s1 + s2;</

文章介绍了scramble字符串算法,该算法将字符串拆分为两部分并可能交换,判断给定的两个字符串s1和s2是否可以通过scramble(s1)得到s2。关键在于遍历所有拆分点,比较字母计数,并使用动态规划避免重复计算。
最低0.47元/天 解锁文章
2147

被折叠的 条评论
为什么被折叠?



