87. 扰乱字符串
使用下面描述的算法可以扰乱字符串 s 得到字符串 t :
如果字符串的长度为 1 ,算法停止
如果字符串的长度 > 1 ,执行下述步骤:
在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 x 和 y ,且满足 s = x + y 。
随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,s 可能是 s = x + y 或者 s = y + x 。
在 x 和 y 这两个子字符串上继续从步骤 1 开始递归执行此算法。
给你两个 长度相等 的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。如果是,返回 true ;否则,返回 false 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/scramble-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
import java.util.Scanner;
class Solution {
private int[][][] dp;
private boolean solve(String s1, int start1, int end1, String s2, int start2, int end2) {
if (dp[start1][start2][end1 - start1] != 0) {
return dp[start1][start2][end1 - start1] == 1;
}
if (start1 == end1) {
if (s1.charAt(start1) == s2.charAt(start2)) {
dp[start1][start2][end1 - start1] = 1;
} else {
dp[start1][start2][end1 - start1] = -1;
}
return dp[start1][start2][end1 - start1] == 1;
}
for (int length = 1; length <= end1 - start1; ++length) {
/**
* 不交换
*/
if (solve(s1, start1, start1 + length - 1, s2, start2, start2 + length - 1)
&& solve(s1, start1 + length, end1, s2, start2 + length, end2)) {
dp[start1][start2][end1 - start1] = 1;
return true;
}
/**
* 交换
*/
if (solve(s1, start1, start1 + length - 1, s2, end2 - length + 1, end2)
&& solve(s1, start1 + length, end1, s2, start2, end2 - length)) {
dp[start1][start2][end1 - start1] = 1;
return true;
}
}
dp[start1][start2][end1 - start1] = -1;
return false;
}
public boolean isScramble(String s1, String s2) {
dp = new int[s1.length()][s1.length()][s1.length()];
return solve(s1, 0, s1.length() - 1, s2, 0, s2.length() - 1);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
System.out.println(new Solution().isScramble(in.next(), in.next()));
}
}
}
心之所向,素履以往 生如逆旅,一苇以航

浙公网安备 33010602011771号