87. 扰乱字符串(动态规划图解)

2024-02-11 07:59

本文主要是介绍87. 扰乱字符串(动态规划图解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

69427e2554f0437e9c120f9fc3d94ae3.png

解题思路:

对于给定的两个字符串S和T。

如果S和T的长度不相等,T肯定不是S的扰乱字符串。

如果S和T的长度相等,则可以在某一个随机下标处进行分割,会将两个字符串S分割成两部分,同理,T也可以用两部分表示,如下如所示:

e55de795f57b4af4a389768df29029b1.png

字符串S被分割为S1和S2,字符串T被分割为T1和T2,此时可以分为两种情况:

  1. 情况一:S1和S2没有交换,此时需要判断T1是否是S1的扰乱字符串,T2是否是S2的扰乱字符串。
  2. 情况二:S1和S2交换了,此时需要判断T2是否是S1的扰乱字符串,T1是否是S1的扰乱字符串。

显然上述分割会将大问题分割成两个小问题:

  1. T1是否是S1的扰乱字符串,T2是否是S2的扰乱字符串
  2. T2是否是S1的扰乱字符串,T1是否是S2的扰乱字符串

子问题的解题步骤和大问题的解题步骤类似,显然可以使用动态规划来求解。

  1. 定义状态:dp[i][j][m][n],表示T[m,...,n]是否是S[i,... ,j]的扰乱字符串,因为如果是扰乱字符串,那个相同部分的长度一定相等,即 n - m = j - i = len,所以可以将四维数组优化为三维数组,d[i][j][len],表示字符串T中从j开始的len个字符串是否是从字符串S中 i 开始的len个字符串的扰乱字符串
  2. 状态转移方程:
    1. 假设随机划分处使得S1的长度为k,如下图所示:f60880da65cf490ea5abaec99872d06e.png
    2. 对于情况一,不交换S1和S2:ee26389346564264a83cc498ab9dbfba.png此时需要判断T1是否是S1的扰乱字符串,T2是否是S2的扰乱字符串,所以dp[i][j][len] = dp[i][j][k] && dp[i+k][j+k][len-k]
    3. 对于情况二,交换S1和S2:e115609c6482439c82a2f75cf372a9b0.png此时需要判断T2是否是S1的扰乱字符串,T1是否是S1的扰乱字符串,注意:需要令T2和S1的长度相等,T1和S2的长度相等,所以,dp[i][j][len] = dp[i][j+len-k][len] && dp[i+k][j][len-k]
    4. 上述只是判断了一处分割位置的状态转移方程,我们需要枚举出所有的分割位置,所以最终的状态转移方程为:dp[i][j][len] = ( dp[i][j][k] && dp[i+k][j+k][len-k] ) || ( dp[i][j+len-k][len] && dp[i+k][j][len-k] ),其中对于每一个len,k都需要从1枚举到 len-1,只要有一个枚举位置可以令 dp[i][j][len] 等于true即可,此时就可以结束枚举了。
  3. 初始状态:两个长度为1的字符串,显然如果这两个字符相等,则 dp[i][j][1] = true,否则false

AC代码:

class Solution {public static boolean isScramble(String s, String t) {int n = s.length();int m = t.length();if (n != m) {return false;}boolean[][][] dp = new boolean[n][n][n + 1];for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {dp[i][j][1] = s.charAt(i) == t.charAt(j);}}for (int len = 2; len <= n; len++) {//枚举s中的位置for (int i = 0; i <= n - len; i++) {//枚举t中的位置for (int j = 0; j <= n - len; j++) {//枚举分割的位置for (int k = 1; k <= len-1; k++) {//不交换S1和S2if(dp[i][j][k]&&dp[i+k][j+k][len-k]){dp[i][j][len]=true;break;}//交换S1和S2if (dp[i][j+len-k][k]&&dp[i+k][j][len-k]){dp[i][j][len]=true;break;}}}}}return dp[0][0][n];}
}

c747e8e96ae2457da43803873162d205.png

 

这篇关于87. 扰乱字符串(动态规划图解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/699280

相关文章

MySQL字符串转数值的方法全解析

《MySQL字符串转数值的方法全解析》在MySQL开发中,字符串与数值的转换是高频操作,本文从隐式转换原理、显式转换方法、典型场景案例、风险防控四个维度系统梳理,助您精准掌握这一核心技能,需要的朋友可... 目录一、隐式转换:自动但需警惕的&ld编程quo;双刃剑”二、显式转换:三大核心方法详解三、典型场景

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

MyBatis-Plus使用动态表名分表查询的实现

《MyBatis-Plus使用动态表名分表查询的实现》本文主要介绍了MyBatis-Plus使用动态表名分表查询,主要是动态修改表名的几种常见场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作... 目录1. 引入依赖2. myBATis-plus配置3. TenantContext 类:租户上下文

Java中的随机数生成案例从范围字符串到动态区间应用

《Java中的随机数生成案例从范围字符串到动态区间应用》本文介绍了在Java中生成随机数的多种方法,并通过两个案例解析如何根据业务需求生成特定范围的随机数,本文通过两个实际案例详细介绍如何在java中... 目录Java中的随机数生成:从范围字符串到动态区间应用引言目录1. Java中的随机数生成基础基本随

基于Nacos实现SpringBoot动态定时任务调度

《基于Nacos实现SpringBoot动态定时任务调度》本文主要介绍了在SpringBoot项目中使用SpringScheduling实现定时任务,并通过Nacos动态配置Cron表达式实现任务的动... 目录背景实现动态变更定时机制配置化 cron 表达式Spring schedule 调度规则追踪定时

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S

Python 常用数据类型详解之字符串、列表、字典操作方法

《Python常用数据类型详解之字符串、列表、字典操作方法》在Python中,字符串、列表和字典是最常用的数据类型,它们在数据处理、程序设计和算法实现中扮演着重要角色,接下来通过本文给大家介绍这三种... 目录一、字符串(String)(一)创建字符串(二)字符串操作1. 字符串连接2. 字符串重复3. 字

Python动态处理文件编码的完整指南

《Python动态处理文件编码的完整指南》在Python文件处理的高级应用中,我们经常会遇到需要动态处理文件编码的场景,本文将深入探讨Python中动态处理文件编码的技术,有需要的小伙伴可以了解下... 目录引言一、理解python的文件编码体系1.1 Python的IO层次结构1.2 编码问题的常见场景二

Java 字符串操作之contains 和 substring 方法最佳实践与常见问题

《Java字符串操作之contains和substring方法最佳实践与常见问题》本文给大家详细介绍Java字符串操作之contains和substring方法最佳实践与常见问题,本文结合实例... 目录一、contains 方法详解1. 方法定义与语法2. 底层实现原理3. 使用示例4. 注意事项二、su