【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. uniCloud的简单使用 增删改查

    新建一个uni-app 项目 启动云开发 选择想要的云服务 在次之前先完成uniCloud 的实名认证 https://unicloud.dcloud.net.cn 有在Web控制台创建过云服务空间就 ...

  2. [POJ2828] Buy Tickets(待续)

    [POJ2828] Buy Tickets(待续) 题目大意:多组测试,每组给出\(n\)条信息\((a,b)\),表示\(b\)前面有\(a\)个人,顺序靠后的信息优先级高 Solution.1 由 ...

  3. k8s 日志收集之 EFK

    如今越来越多的应用部署在容器之中,如何收集日志也是一个很重要的问题.服务出问题了,排查问题需要给开发看日志.服务一般会在多个不同的 pod 中,一个一个的登进去看也的确不方便.业务数据统计也需要日志. ...

  4. CSS-clear属性的作用

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  5. C/C++ 性能优化背后的方法论:TMAM

    开发过程中我们多少都会关注服务的性能,然而性能优化是相对比较困难,往往需要多轮优化.测试,属于费时费力,有时候还未必有好的效果.但是如果有较好的性能优化方法指导.工具辅助分析可以帮助我们快速发现性能瓶 ...

  6. Go语言GC实现原理及源码分析

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/475 本文使用的 Go 的源码1.15.7 介绍 三色标记法 三色标 ...

  7. Mysql之案例分析(一)

    可见性分析 CREATE TABLE `t` ( `id` int(11) NOT NULL, `k` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGIN ...

  8. [Fundamental of Power Electronics]-PART II-8. 变换器传递函数-8.5 交流传递函数以及阻抗的测量/8.6 本章小结

    8.5 交流传递函数以及阻抗的测量 测量原型变换器和变换器系统的传递函数是非常好的工程实践过程.这样的实践可以验证系统是否被正确地建模和设计.此外,通过测量单个电路元件的端阻抗来表征其特性也是非常有用 ...

  9. java面试-死锁产生、定位分析和修复

    死锁发生:两个或多个线程之间,互相持有对方需要的锁,而永久处于阻塞状态 一.手写死锁代码: public class DeadLockSample extends Thread { private S ...

  10. 201871030134-余宝鹏 实验二 个人项目一 《D{0-1}KP》项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业要求 我的课程学习目标 1.掌握软件项目个人开发流程2.掌握Github发布软件项目的操作方法 这个作业帮助我在哪些方面实现学习目标 1. ...