87.扰乱字符串
题目描述:
使用以下方法扰乱字符串 $s$ 得到字符串 $t$ :
如果字符串的长度为 $1$ ,算法终止
如果长度大于 $1$ ,按照以下顺序执行:
在随机下标处将 $s$ 分割为 $x,y$ ;
随机组合得到 $x+y$ 或者 $y + x$ ;
继续对生成的字符串执行上述操作
给出两个长度相等的字符串 $s1,s2$ ,判断 $s2$ 是否是 $s1$ 经过扰乱产生的。
数据范围:
$1\le n\le 30$
题解:
如果长度不同,或者同一个字符出现的次数不同则一定不能产生。如果两个字符串相同直接返回。
其他的情况需要对字符串进行分割。需要枚举分割点,将 $s1$ 分割为 $x1,x2$ ,将 $s2$ 分割为 $y1,y2$ 。判断 $(x1,y1)(x2,y2)$ 或者 $(x1,y2)(x2,y1)$ 是否是通过扰动产生。
可以使用 $dp[index1][index2][len]$ 来表示以 $s1[index1],s2[index2]$ 为起点的长度为 $len$ 的字符串是否是通过扰动产生的。
那么
不方便枚举,可以使用记忆化搜索。
如果使用递推需要确定枚举 $i,j,len$ 的顺序以及初始化条件。其实就是一个区间 $dp$ 。
初始条件为:只有一个字符并且相等则为 $true$ 。即 $dp[i][j][1] = true;s1[i]=s2[j]$
枚举顺序:
- 先枚举 $len$ ,因为后面的长度需要更小的长度的结果。 $2\le len \le n$
- 因为长度更短的已经算出来了,所以 $i$ 和 $j$ 的枚举顺序没有要求。
这个题目由于有效状态比较少,记忆化搜索的速度更快。
代码:
1 | class Solution |
1 | class Solution |