扰乱字符串

使用下面描述的算法可以扰乱字符串 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 static boolean isOk(char[] str1, char[] str2, int L1, int L2, int length, int[][][] dp) {
        if (dp[L1][L2][length] != -1) {
            return dp[L1][L2][length] == 1;
        }
        if (length == 1) {
            return str1[L1] == str2[L2];
        }
        for (int i = 1; i < length; ++i) {
            if (isOk(str1, str2, L1, L2, i, dp) && isOk(str1, str2, L1 + i, L2 + i, length - i, dp)) {
                dp[L1][L2][length] = 1;
                return true;
            }
            if (isOk(str1, str2, L1, L2 + length - i, i, dp) && isOk(str1, str2, L1 + i, L2, length - i, dp)) {
                dp[L1][L2][length] = 1;
                return true;
            }
        }
        dp[L1][L2][length] = 0;
        return false;
    }

    public static boolean isScramble(String s1, String s2) {
        if (s1 == null || s1.length() == 0 || s2 == null || s2.length() == 0) {
            return false;
        }
        if (s1.length() != s2.length()) {
            return false;
        }
        if (s1.equals(s2)) {
            return true;
        }
        char[] str1 = s1.toCharArray();
        char[] str2 = s2.toCharArray();
        int[] map = new int[256];
        for (int i = 0; i < str1.length; ++i) {
            map[str1[i]]++;
        }
        for (int i = 0; i < str2.length; ++i) {
            if (--map[str2[i]] < 0) {
                return false;
            }
        }
        int[][][] dp = new int[str1.length][s1.length()][str1.length + 1];
        for (int i = 0; i < s1.length(); ++i) {
            for (int j = 0; j < s2.length(); ++j) {
                for (int k = 0; k <= s1.length(); ++k) {
                    dp[i][j][k] = -1;
                }
            }
        }
        return isOk(str1, str2, 0, 0, str1.length, dp);
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String str1 = in.next();
            String str2 = in.next();
            System.out.println(isScramble(str1, str2));
        }
    }
}
上一篇:C语言之数字提取


下一篇:STL——string容器