【python】Leetcode每日一题-扰乱字符串

【题目描述】

使用下面描述的算法可以扰乱字符串 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 。

示例1:

输入:s1 = "great", s2 = "rgeat"
输出:true
解释:s1 上可能发生的一种情形是:
"great" --> "gr/eat" // 在一个随机下标处分割得到两个子字符串
"gr/eat" --> "gr/eat" // 随机决定:「保持这两个子字符串的顺序不变」
"gr/eat" --> "g/r / e/at" // 在子字符串上递归执行此算法。两个子字符串分别在随机下标处进行一轮分割
"g/r / e/at" --> "r/g / e/at" // 随机决定:第一组「交换两个子字符串」,第二组「保持这两个子字符串的顺序不变」
"r/g / e/at" --> "r/g / e/ a/t" // 继续递归执行此算法,将 "at" 分割得到 "a/t"
"r/g / e/ a/t" --> "r/g / e/ a/t" // 随机决定:「保持这两个子字符串的顺序不变」
算法终止,结果字符串和 s2 相同,都是 "rgeat"
这是一种能够扰乱 s1 得到 s2 的情形,可以认为 s2 是 s1 的扰乱字符串,返回 true

示例2:

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

示例3:

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

提示:

s1.length == s2.length
1 <= s1.length <= 30
s1 和 s2 由小写英文字母组成

【分析】

  • dp难呀

    话不多说,先上题解

    方法一:暴力递归(即官方解法python代码

    class Solution:
    def isScramble(self, s1: str, s2: str) -> bool:
    @cache
    def dfs(i1: int, i2: int, length: int) -> bool:
    """
    第一个字符串从 i1 开始,第二个字符串从 i2 开始,子串的长度为 length,是否和谐
    """ # 判断两个子串是否相等
    if s1[i1:i1+length] == s2[i2:i2+length]:
    return True # 判断是否存在字符 c 在两个子串中出现的次数不同
    if Counter(s1[i1:i1+length]) != Counter(s2[i2:i2+length]):
    return False # 枚举分割位置
    for i in range(1, length):
    # 不交换的情况
    if dfs(i1, i2, i) and dfs(i1 + i, i2 + i, length - i):
    return True
    # 交换的情况
    if dfs(i1, i2 + length - i, i) and dfs(i1 + i, i2, length - i):
    return True return False ans = dfs(0, 0, len(s1))
    dfs.cache_clear()
    return ans

    方法二:记忆化搜索(即预定义数组,递归过程中直接调用已计算值,思想类似于预处理,dp

    class Solution:
    def isScramble(self, s1: str, s2: str) -> bool:
    demo = [[[None for i in range(31)] for i in range(31)] for i in range(31)]
    @cache
    def dfs(i1: int, i2: int, length: int) -> bool:
    if demo[i1][i2][length] != None:
    return demo[i1][i2][length]
    """
    第一个字符串从 i1 开始,第二个字符串从 i2 开始,子串的长度为 length,是否和谐
    """ # 判断两个子串是否相等
    if s1[i1:i1+length] == s2[i2:i2+length]:
    demo[i1][i2][length] = True
    return True # 枚举分割位置
    for i in range(1, length):
    # 不交换的情况
    if dfs(i1, i2, i) and dfs(i1 + i, i2 + i, length - i):
    demo[i1][i2][length] = True
    return True
    # 交换的情况
    if dfs(i1, i2 + length - i, i) and dfs(i1 + i, i2, length - i):
    demo[i1][i2][length] = True
    return True
    demo[i1][i2][length] = False
    return False ans = dfs(0, 0, len(s1))
    dfs.cache_clear()
    return ans

    方法三:区间dp

    // 对应了「s1 的 [0,i) & [i,n)」匹配「s2 的 [0,i) & [i,n)」
    if (dfs(i, j, k) && dfs(i + k, j + k, len - k)) {
    cache[i][j][len] = Y;
    return true;
    }
    // 对应了「s1 的 [0,i) & [i,n)」匹配「s2 的 [n-i,n) & [0,n-i)」
    if (dfs(i, j + len - k, k) && dfs(i + k, j, len - k)) {
    cache[i][j][len] = Y;
    return true;
    }
    class Solution:
    def isScramble(self, s1: str, s2: str) -> bool:
    if s1 == s2:
    return True
    if len(s1) != len(s2):
    return False
    length = len(s1)
    demo = [[[False for i in range(length+1)] for i in range(length)] for i in range(length)] for i in range(length):
    for j in range(length):
    demo[i][j][1] = s1[i] == s2[j] for l in range(2, length+1):
    for i in range(length - l + 1):
    for j in range(length - l + 1):
    for k in range(1, l):
    a = demo[i][j][k] and demo[i + k][j + k][l - k];
    b = demo[i][j + l - k][k] and demo[i + k][j][l - k];
    if (a or b):
    demo[i][j][l] = True
    return demo[0][0][length]

    yysy,不知道为啥,后面两种leetcode时间消耗还更大,估计是内存频繁创建demo数组原因

【python】Leetcode每日一题-扰乱字符串的更多相关文章

  1. 【python】Leetcode每日一题-前缀树(Trie)

    [python]Leetcode每日一题-前缀树(Trie) [题目描述] Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的 ...

  2. 【python】Leetcode每日一题-最大数

    [python]Leetcode每日一题-最大数 [题目描述] 给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数. 注意:输出结果可能非常大,所以你需要返回一个 ...

  3. 【python】Leetcode每日一题-最长公共子序列

    [python]Leetcode每日一题-最长公共子序列 [题目描述] 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度.如果不存在 公共子序列 ,返回 0 . ...

  4. 【python】Leetcode每日一题-不同的子序列

    [python]Leetcode每日一题-不同的子序列 [题目描述] 给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数. 字符串的一个 子序列 是指,通过删除一些(也可以 ...

  5. 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素

    [python]Leetcode每日一题-寻找旋转排序数组中的最小元素 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...

  6. 【python】Leetcode每日一题-删除有序数组中的重复项

    [python]Leetcode每日一题-删除有序数组中的重复项 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现一次 ,返回删除后数组的新长度. 不要 ...

  7. 【python】Leetcode每日一题-存在重复元素3

    [python]Leetcode每日一题-存在重复元素3 [题目描述] 给你一个整数数组 nums 和两个整数 k 和 t .请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] ...

  8. 【python】Leetcode每日一题-打家劫舍2

    [python]Leetcode每日一题-打家劫舍2 [题目描述] 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金.这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋 ...

  9. 【python】Leetcode每日一题-二叉搜索树节点最小距离

    [python]Leetcode每日一题-二叉搜索树节点最小距离 [题目描述] 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 示例1: 输入:root = [4 ...

随机推荐

  1. cpu缓存和volatile

    目录 CPU缓存的由来 CPU缓存的概念 CPU缓存的意义 缓存一致性协议-MESI协议 Store Buffers Store Forwarding Memory Barriers Invalida ...

  2. MyBatis(七):MyBatis缓存详解(一级缓存/二级缓存)

    一级缓存 ​ MyBatis一级缓存上SqlSession缓存,即在统一SqlSession中,在不执行增删改操作提交事务的前提下,对同一条数据进行多次查询时,第一次查询从数据库中查询,完成后会存入缓 ...

  3. python基础学习之类

    面向对象和面向过程 面向过程:以吃饭为例,即为 煮饭.洗菜.洗碗.切菜.炒菜.出锅.吃饭面向对象:目标对象做完,直接吃疑问点:1.面向对象就是把过程用函数封装起来,随时调用?:2.面向过程就是每次都把 ...

  4. cadence Virtuoso ADE原理图AnalogLib库中的switch使用

    Symbol: switch A,B:等效于一个电阻; C,D:等效于控制开关(CD间的控制电压控制AB的断开或闭合); open switch resistance:开关断开状态下的等效电阻(AB之 ...

  5. 使用Jenkins + git submodule 实现自动化编译,解决代码安全性问题

    道哥的第 030 篇原创 目录 一.一个真实的代码泄漏故事 二.Jenkins 的基本使用 1. Jenkins 是什么? 2. 安装 JDK8 3. 安装 Jenkins 4. 在浏览器中配置 Je ...

  6. Java学习之this关键字的使用

    •区分成员变量和局部变量 public class Person { String name; int age; public void set(String name,int age) { this ...

  7. javascript 取自己

    var own=docment.currentScript;

  8. Nginx记录用户请求Header到access log

    为了统计和其它用途,经常有人需要自定义Nginx日志,把http请求中的某个字段记录到日志中,刚好在看lua+nginx的文章,第一想到的是用lua赋值来做,但是想想有点小恶心,于是Google了一番 ...

  9. Django中 render() 函数的使用方法

    render() 函数 在讲 render() 函数之前,我们在 Django 项目 index 文件夹的 urls.py 和 views.py 中编写如下功能代码:(不难,望读者细心阅之) # in ...

  10. day16.网络编程1

    1 osi七层,tcp/ip 5层 1 cs架构和bs架构 2 互联网 3 osi七层.5层(5层名字记住:重点) -物理层 -网线,光纤 -数据链路层 -网卡 -网络层 -路由器 -传输层(运输层) ...