力扣0087——扰乱字符串

扰乱字符串

难度:困难

题目描述

使用下面描述的算法可以扰乱字符串 s 得到字符串 t

  1. 如果字符串的长度为 1 ,算法停止
  2. 如果字符串的长度 > 1 ,执行下述步骤:
    • 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 xy ,且满足 s = x + y
    • 随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,s 可能是 s = x + y 或者 s = y + x
    • xy 这两个子字符串上继续从步骤 1 开始递归执行此算法。

给你两个 长度相等 的字符串 s1s2,判断 s2 是否是 s1 的扰乱字符串。如果是,返回 true ;否则,返回 false

示例1

输入: s1 = "great", s2 = "rgeat"
输出: true

示例2

输入: s1 = "abcde", s2 = "caebd"
输出: false

示例3

输入: s1 = "a", s2 = "a"
输出: true

题解

直接使用动态规划来解题,原始的递归方法中存在大量的重复操作,从而使时间复杂度大幅提高,这时可以使用一个三维数组dp[i][j][k]来记录,i表示s1起始位置,j表示s2起始位置,k表示当前字符串的长度

转移方程如下:

dp[i,j,k] = (dp[i,j,m] && dp[i+m,j+m,k-m]) || (dp[i,j+k-m,m] && dp[i+m,j,k-m])

其中m的取值范围是[1,k)。这表示切割位置可以在1到k之间选择。

想法代码

csharp 复制代码
using System;
using System.Net.Http.Headers;

class Solution
{
    List<List<string>> strings = new List<List<string>>();
    public static void Main(string[] args)
    {
        string s1 = "great";
        string s2 = "rgeat";
        Solution solution = new Solution();
        bool ans = solution.IsScramble(s1, s2);
        Console.WriteLine(ans);
    }

    public bool IsScramble(string s1, string s2)
    {
        if (s1.Equals(s2))
        {
            return true;
        }

        int length = s1.Length;
        int[,,] dp = new int[length, length, length + 1];

        for (int k = 1; k <= length; k++)
        {
            for (int i = 0; i <= length - k; i++)
            {
                for (int j = 0; j <= length - k; j++)
                {
                    if (k == 1)
                    {
                        dp[i, j, k] = s1[i] == s2[j] ? 1 : 0;
                        continue;
                    }

                    for (int m = 1; m < k; m++)
                    {
                        if ((dp[i, j, m] == 1 && dp[i + m, j + m, k - m] == 1) || (dp[i, j + k - m, m] == 1 && dp[i + m, j, k - m] == 1))
                        {
                            dp[i, j, k] = 1;
                            break;
                        }
                    }
                }
            }
        }

        return dp[0, 0, length] == 1;
    }
}
相关推荐
fqq35 小时前
java基础面试题目
面试·职场和发展
Orz_Sponge_Bob6 小时前
温州市第三届青少年程序设计竞赛(小学组)题解
算法
小江的记录本6 小时前
【Java并发编程】锁机制:volatile:JMM内存模型、可见性/禁止指令重排、内存屏障、单例模式中的应用(附《思维导图》+《面试高频考点清单》)
java·后端·python·mysql·单例模式·面试·职场和发展
Noushiki6 小时前
常见的排序算法
算法·排序算法
gumichef6 小时前
二叉树链式结构的实现
算法·链表·二叉树·队列
战南诚6 小时前
力扣 之 198.打家劫舍
python·算法·leetcode
AllData公司负责人6 小时前
亲测丝滑,体验跃迁|AllData通过集成开源项目StreamPark,实时流任务调度更省心!
java·大数据·数据库·人工智能·算法·实时计算·实时开发平台
计算机安禾6 小时前
【c++面向对象编程】第46篇:CRTP(奇异递归模板模式):静态多态的妙用
开发语言·c++·算法
广州灵眸科技有限公司6 小时前
瑞芯微(EASY EAI)RV1126B 音频电路
开发语言·人工智能·深度学习·算法·yolo·音视频
小的~~6 小时前
算法题:只出现一次的数字
数据结构·算法