[LeetCode]87. 扰乱字符串(java实现)动态规划

1. 题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 读题(需要重点注意的东西)

思路一(闫式dp分析法):
f[i,j,k] 表示的是能否将长度为 k 的字符串 S1[i,i+k-1] 通过一些操作(分割+交换)转换为 长度为 S2[j,j+k-1] 的字符串,是一个 boolean 值。
在这里插入图片描述
思路二(递归):

注: 递归解法现在已经超时了,其时间复杂度为O(5^n^)

假设字符串的长度是n,遍历所有可能的分割情况,将s1分割成[0, i) [i, n),s2由于可能翻转,所以可能是[0, i)和[i, n)也可能是[n - i, n)和[0, n - i);分段比较长度相同的字符串,将它们进行排序,若相同的话,则排序后的字符串是相同的,考虑翻转与否两种情况:

  1. 不进行翻转:isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i, n), s2.substring(i, n))
    在这里插入图片描述

  2. 进行翻转:isScramble(s1.substring(0, i), s2.substring(n - i, n))
    && isScramble(s1.substring(i, n), s2.substring(0, n - i))
    在这里插入图片描述

不断递归在不同点处进行分割的子串,直到s1 == s2,返回true。

3. 解法

---------------------------------------------------解法1:dp---------------------------------------------------

class Solution {
    public boolean isScramble(String s1, String s2) {
        int n = s1.length();
        boolean[][][] f = new boolean[n][n][n+1];
        for (int k = 1; k <= n; k ++ )
            for (int i = 0; i + k - 1 < n; i ++ )
                for (int j = 0; j + k - 1 < n; j ++ ) {
                    if (k == 1) {
                        if (s1.charAt(i) == s2.charAt(j)) f[i][j][k] = true;
                    } else {
                        for (int u = 1; u < k; u ++ ) {
                            if (f[i][j][u] && f[i + u][j + u][k - u] || f[i][j + k - u][u] && f[i + u][j][k - u]) {
                                f[i][j][k] = true;
                                break;
                            }
                        }
                    }
                }
        return f[0][0][n];
    }
}

可能存在的问题:

---------------------------------------------------解法2:递归--------------------------------------------------

class Solution {
    public String sort(String s1){
        char[] str = s1.toCharArray();
        Arrays.sort(str);
        return String.valueOf(str);
    }
    public boolean isScramble(String s1, String s2) {
        if(s1.equals(s2)) return true;
        if(!sort(s1).equals(sort(s2))) return false;
        int n = s1.length();
        for(int i = 1;i <= n - 1;i++){
            if(isScramble(s1.substring(0, i), s2.substring(0, i))&& isScramble(s1.substring(i, n), s2.substring(i, n))) return true;
            if(isScramble(s1.substring(0, i), s2.substring(n - i, n))&& isScramble(s1.substring(i, n), s2.substring(0, n - i))) return true;
        }
        return false;
    }
}

可能存在的问题:
注意: String对象的比较需要使用equals(),不能直接使用==,详见java:String使用equals和==比较的区别
在这里插入图片描述
在这里插入图片描述

4. 可能有帮助的前置习题

5. 所用到的数据结构与算法思想

  • dp
  • dfs

6. 总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Cloudeeeee

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

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

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

打赏作者

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

抵扣说明:

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

余额充值