Leetcode87. 扰乱字符串

题目传送地址:https://leetcode.cn/problems/scramble-string/

运行效率:
在这里插入图片描述
代码如下:

class Solution {
   String s1;
    String s2;
    int[][][] dp;

    public boolean isScramble(String s1, String s2) {
        int s1Length = s1.length();
        int s2Length = s2.length();
        if (s1Length != s2Length) {
            return false;
        }
        //下面之所以要+1的原因, 是因为后面我们会用到  dp[i][j][length] 避免越界的情况产生
        int[][][] dp = new int[s1Length][s1Length][s1Length + 1];
        this.s1 = s1;
        this.s2 = s2;
        this.dp = dp;
        boolean df = df(0, 0, s1Length);
        return df;
    }

    // 第一个字符串从 i1 开始,第二个字符串从 i2 开始,子串的长度为 length,是否和谐s
    public boolean df(int i, int j, int length) {
    //如果dp[i][j][length]曾经被计算过了,那就直接用就行
        if (dp[i][j][length] != 0) {
            return dp[i][j][length] == 1;
        }
        String substring1 = this.s1.substring(i, i + length);
        String substring2 = this.s2.substring(j, j + length);
        //处理边界情况
        if (substring1.equals(substring2)) {
            dp[i][j][length] = 1;
            return true;
        }
        if (!checkIfSimilar(substring1, substring2)) {
            dp[i][j][length] = -1;
            return false;
        }
        //n是分割线
        for (int n = 1; n < length; n++) {
            //不交换 的情况
            boolean df1 = df(i, j, n);
            boolean df2 = df(i + n, j + n, length - n);
            if (df1 && df2) {
                dp[i][j][length] = 1;
                return true;
            }
            //交换 的情况
            boolean df3 = df(i, j + length - n, n);//s1前半段和s2后半段做对比
            boolean df4 = df(i + n, j, length - n); //s1后半段和s2前半段做对比
            if (df3 && df4) {
                dp[i][j][length] = 1;
                return true;
            }
        }
        dp[i][j][length] = -1;
        return false;
    }

    /**
     * 校验两个字符串里的各字符数目是否一致
     *
     * @param s1
     * @param s2
     * @return
     */
    public static boolean checkIfSimilar(String s1, String s2) {
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < s1.length(); i++) {
            char c = s1.charAt(i);
            if (map.containsKey(c)) {
                Integer integer = map.get(c);
                map.put(c, integer + 1);
            } else {
                map.put(c, 1);
            }
        }

        for (int j = 0; j < s2.length(); j++) {
            char c = s2.charAt(j);
            if (map.containsKey(c)) {
                Integer integer = map.get(c);
                map.put(c, integer - 1);
            } else {
                return false;
            }
        }
        for (Map.Entry<Character, Integer> entry : map.entrySet()) {
            if (entry.getValue() != 0) {
                return false;
            }
        }
        return true;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java全栈研发大联盟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值