【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. TensorFlow学习(2)

    TensorFlow学习(2) 一.jupyter notebook的安装和使用 1. 什么是jupyter notebook jupyter notebook(http://jupyter.org/ ...

  2. Hive中静态分区和动态分区总结

    目录 背景 第一部分 静态分区 第二部分 动态分区 第三部分 两者的比较 第四部分 动态分区使用的问题 参考文献及资料 背景 在Hive中有两种类型的分区:静态分区(Static Partitioni ...

  3. 用DeBug的方式,带你掌握HBase文件在Snapshot的各种变化

    摘要:掌握Snapshot可以帮助我们很好的完成HBase数据备份和数据迁移的工作. 简介 HBase的Snapshot功能可以在不复制数据的情况下,快速克隆一张表,完成一次数据备份.通过Snapsh ...

  4. 系统编程-信号-总体概述和signal基本使用

    信号章节 -- 信号章节总体概要 信号基本概念 信号是异步事件,发送信号的线程可以继续向下执行而不阻塞. 信号无优先级. 1到31号信号是非实时信号,发送的信号可能会丢失,不支持信号排队. 31号信号 ...

  5. Linux 软链接link/ln -s

    在Linux中,链接分为软的和硬的,至于两者之间有什么差别,大家可以参考下https://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-li ...

  6. [Fundamental of Power Electronics]-PART II-9. 控制器设计-9.5 控制器的设计

    9.5 控制器设计 现在让我们来考虑如何设计控制器系统,来满足有关抑制扰动,瞬态响应以及稳定性的规范或者说设计目标.典型的直流控制器设计可以用以下规范定义: 1.负载电流变化对输出电压调节的影响.当负 ...

  7. .NET Request对象介绍

    Request对象用于检索从浏览器向服务器所发送的请求信息.它提供对当前页请求的访问,包括标题,Cookie,客户端证书等等.它也与HTTP协议的请求消息对应 Request常用的属性 属性 具体内容 ...

  8. Leedcode算法专题训练(动态规划)

    递归和动态规划都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划保存了子问题的解,避免重复计算. 斐波那契数列 1. 爬楼梯 70. Climbing Stairs (Easy) L ...

  9. CrackMe_002

    老规矩,先熟悉程序. 只有一个验证的功能,错误提示You Get ... 关闭没有nag窗口 第一种,暴力破解 查找字符串,很少,直接双击进入 可以看到错误提示的跳转来自: 表示这应该是个重要的跳转, ...

  10. VirtualBox虚拟机读取U盘

    1 概述 使用VirtualBox虚拟机(系统Win10)读取宿主机(系统Manjaro)中的U盘. 2 安装扩展 戳这里下载对应版本的一个叫Oracle_VM_VirtualBox_Extensio ...