LeetCode 87,远看是字符串其实是搜索,你能做出来吗?

Java实现 LeetCode 87 扰乱字符串 87. 扰乱字符串 给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树。 下图是字符串 s1 = “great” 的一种可能的表示形式。 great / \ gr eat / \ / \ g r e at / \ a t 在扰乱这个字符串的过程中,我们可以挑选任何一个... 阅读详情

本文始发于个人公众号:TechFlow,原创不易,求个关注


今天是LeetCode专题第54篇文章,我们一起来看LeetCode 87题,Scramble String(爬行字符串)。

这题的官方难度是Hard,通过率33%,点赞506,反对702。看起来这题难度还可以,但是反对比点赞多,其实这题质量还不错,反对比较多我猜可能是因为题意稍稍有些复杂,理解起来不太容易,编码也偏难。但是这题如果是放在正式比赛中出现的话,都不叫事。

下面我们来看下题意。


题意


这题的题目叫做爬取字符串,看起来有些费解,其实这个爬取是题目中定义出来的一种操作,我们稍候结合样例来看很容易理解。首先,我们先把一个字符串拆分成二叉树的形式。

   great
   /    \
  gr    eat
 / \    /  \
g   r  e   at
           / \
          a   t

也就是我们随机的选择分段点,每次都将字符串分割成两个部分。有了这棵二叉树之后,我们就可以进行爬取操作了。所谓的爬取操作,也就是调换这棵二叉树当中某一个节点的左右孩子的顺序。比如假设我们选择了对gr这个节点进行爬取,那么得到的结果如下:

    rgeat
   /    \
  rg    eat
 / \    /  \
r   g  e   at
           / \
          a   t

我们还可以多次执行爬取,比如我们多次爬取操作之后可以得到一个全新的字符串rgtae.

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a

rgeat和rgtae都是从原字符串great进行一系列爬取操作之后得到的,题目会给定两个字符串s1和s2,要求我们给出能否通过对s1爬取操作得到字符串s2?


题解


不知道大家看完题意是什么感觉,是否觉得有些棘手呢?

棘手归棘手,但题目的要求还是很明确的。还是老规矩,我们一点点来分析问题。首先,那个花里胡哨的爬取操作是一个可逆操作,也就是说如果字符串s1能够通过这些操作变成s2,那么同样s2也可以通过同样的操作变回s1。从更高的层面来说,它们其实是一样的,是同一个存在的两个状态。

进一步,如果大家学过图论相关的算法,对这块有所了解的话,那么这个问题还可以进一步变形。

假设我们最初的字符串是s,它通过一步爬取操作可以变成s1,s2和s3。那么我们可以把这些字符串都抽象成一张无向图当中的节点。可以看成是s和s1,s2和s3之间有一条边相连。所以字符串之间能否通过爬取转化的关系就变成了在图上是否联通的关系,这个问题也就变成了在一张无向图当中已知两点,请问这两点是否联通。这个问题就简单多了,我们遍历整张图就好了。

缩小到了图上遍历之后,整个问题其实已经出来了,遍历图无非两种方法,一种是深度优先搜索,一种是宽度优先搜索。这两种都是老掉牙的算法了,实在没什么稀奇的。在这题当中深搜宽搜都差不多,看你的喜好了。我个人是选择的深搜实现的。

对于字符串的爬取操作而言,一共有两种可能,一种是s1拆分之后的两个部分分别和s2同样位置的两个部分的字符串进行比较。还有一种可能是s1的前半部分和s2的后半部分,s1的后半部分和s2的前半部分判断。这两种情况其实是同一个节点在搜索树上的两个支路,相当于我们提前剪枝了,剪掉了不可能存在解的搜索子树,这个也是剪枝的常规做法。

大家可能感觉这个题意比较复杂,但是最后的代码也许要比大家想的要简单:

class Solution:
    def isScramble(self, s1: str, s2: str) -> bool:
        from collections import Counter
        
        def determine(s1, s2):
            # 如果s1和s2构成的字符不同,那么直接排除
            c1 = Counter(list(s1))
            c2 = Counter(list(s2))
            return c1 == c2

        
        def dfs(s1, s2):
            # 如果要判断的s1和s2相等,返回True
            if s1 == s2:
                return True
            if not determine(s1, s2):
                return False
            n = len(s1)
            # 枚举拆分的位置将字符串拆分成两个部分
            for i in range(1, n):
                if dfs(s1[:i], s2[:i]) and dfs(s1[i:], s2[i:]) or dfs(s1[:i], s2[n-i:]) and dfs(s1[i:], s2[:n-i]):
                    return True
            return False
        
            
        if len(s1) != len(s2):
            return False
        if len(s1) == 0:
            return True
        return dfs(s1, s2)

总结


今天的这道题就算是讲完了,虽然看起来涉及到各种字符串的操作,又是建树又是颠倒顺序什么的,但这题本质上其实是一道搜索题。只要对搜索问题稍微熟悉一点,做出这道题并不困难,这也是本题通过率其实不算低的原因。

在之前的文章当中也曾经提到过,不管是在LeetCode上也好,还是在acm赛场上也罢,一道看似是字符串的问题最后通过建模转化成其他的算法模型是家常便饭的事情。大家做题的时候一定要思维灵活,如果钻了牛角尖可能就解不出来了。

今天的文章到这里就结束了,如果喜欢本文的话,请来一波素质三连,给我一点支持吧(关注、转发、点赞)。

在这里插入图片描述

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

相关推荐

Leetcode No.87 扰乱字符串(动态规划)

一、题目描述 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行下述步骤: 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 x 和 y ,且满足 s = x + y 。 随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,s 可能是 s = x + y 或者 s = y + x 。 在 x 和 y 这两个子字符串上继续从步骤

594

leetcode:87. 扰乱字符串

题目来源 leetcode 题目描述 题目解析 题意: 给定一个字符串S,按照树结构每次二分成左右两个部分,直到单个字符 在树上某些节点交换左右儿子,可以形成新的字符串 判断一个字符串T是否由S经过这样的变化而成 例子1: 这是一道区间型状态规划: 给定一个序列或者字符串进行一些操作,从最后一步出发,将序列或者字符串去头、去尾… 区间型dp一般用dp[i][j],i表示左端点,j表示右端点,如果有其他维度可以再添加,如果两个端点之间有联系,则可以再压缩空间 动态规划 (1)确定状态

OceanStar的博客 408

鸿蒙之HML语法参考

HML(HarmonyOS Markup Language)是一套类HTML的标记语言,通过组件,事件构建出页面的内容。页面具备数据绑定、事件绑定、条件渲染和逻辑控制等高级能力。

2401_82772199的博客 1648

LeetCode 题目 87:递归\动态规划\哈希实现 扰乱字符串

LeetCode 题目 87:递归\动态规划\哈希实现 扰乱字符串

10年数据\经营分析经验,现任大厂数据分析负责人 142

matianl:SAP 最详细的权限管理解析

上文所说的系统自带权限对象与权限字段仅能满足有限的需要,其权限审核的逻辑也是系统硬编码了的,我们能做的只是是否启用某项权限对象的检查(使用SU22)。如果需要自定义,通过SU20、SU21定义即可。

matinal 當冬夜漸暖 。公众号:matinal 2153

半导体制造技术导论(第二版)萧宏 第五章集成电路加热工艺答案

第二次退火是在较高温度下进行,并将电阻系数较高的c49碳化硅转变为电阻系数较低的c54碳。水平式高温炉加热、垂直式高温炉加热(即传统的管式炉加热)、快速加热工艺RTP、激光镭射。8. 集成电路芯片制造过程中,会使用垫底氧化层、阻挡氧化层、栅氧氧化层、屏蔽氧化层和全。氧化是最重要的加热过程之一,是一种添加工艺,将氧气加入到硅晶圆后,在晶圆表面形成二氧。为了满足元器件性能的要求,必须利用退火工艺将晶格的损伤修复,使其恢复单晶结构并激活掺。工艺氮气气流下将晶舟推入炉管,升高温度,稳定温度;

goal_achieving的博客 1863

LeetCode 87:扰乱字符串

给定两个长度相同的字符串s1和s2,判断s2是否是s1的。xyxy。

m0_75126572的博客 1200

10、皮肤 - 神经记录实验全流程解析

本博客详细介绍了皮肤-神经记录实验的全流程,涵盖实验所需的材料准备和具体操作方法。内容包括细胞外记录设备的设置、合成间质液(SIF)的制备与调节、小鼠后爪皮肤和胫神经的手术解剖步骤、清洁解剖后的记录准备、纤维分离与感受野识别方法,以及神经纤维机械响应的测量。该实验为研究神经纤维的活动与功能提供了重要的技术支持,适用于神经科学研究领域。

backprop5master的博客 184

算法leetcode|87. 扰乱字符串(rust重拳出击)

使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行下述步骤: 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 x 和 y ,且满足 s = x + y 。 随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,s 可能是 s = x + y 或者 s = y + x 。 在 x 和 y 这两

二当家的白帽子 1869

021、反激变换器的软启动设计

本文分享了反激变换器软启动设计的实践经验。作者通过一次上电炸机事故引出软启动的重要性,分析了启动瞬间电流冲击和环路饱和问题。介绍了三种软启动方案:效果差的RC电路、推荐使用的数字芯片方案以及分立元件实现方法,重点指出数字方案的一致性优势。文章还探讨了软启动与过流保护的配合问题,提供了实测波形、温度影响等调试要点,并总结出软启动时间选择、批量生产一致性等实用建议。最后强调软启动是电源可靠性的关键设计,不应为节省成本而忽略。全文包含多个工程实践细节,对电源设计人员具有重要参考价值。(149字)

Jack010169的博客 173

【报错解决】OpenClaw 报错 `openclaw: command not found`:全局命令未加入系统 PATH 的深度排查与修复指南

在国产AI工具链开发中,OpenClaw作为关键命令行工具常出现command not found报错。本文深度分析该问题的根源——Linux环境变量PATH未包含用户级安装目录(~/.local/bin)。通过四种解决方案(临时PATH修改、永久配置、软链接、虚拟环境处理)和排错Checklist,揭示"命令存在却找不到"的本质是路径配置问题,特别适用于Docker/国产Linux/非root环境。文中强调理解Linux工具链机制对国产AI开发的重要性,并指出这是开发者掌握环境

博客 5381

LeetCode第87题(扰乱字符串)

原题如下: 给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树。 下图是字符串 s1 = “great” 的一种可能的表示形式。 great / gr eat / \ / g r e at / a t 在扰乱这个字符串的过程中,我们可以挑选任何一个非叶节点,然后交换它的两个子节点。 例如,如果我们挑选非叶节点 “gr” ,...

qq_42203013的博客 694

YOLO26-Quantized:面向国产AI芯片的全栈量化方案,适配昇腾310P与寒武纪MLU270

在算力国产化替代的行业趋势下,昇腾310P、寒武纪MLU270已成为工业边缘视觉、智能检测场景的主流国产AI芯片选型。针对原生YOLO26模型在国产芯片上推理效率低、算子兼容性差、量化精度塌陷三大核心痛点,本文提出YOLO26-Quantized全栈量化方案,覆盖训练感知量化(QAT)、离线静态量化(PTQ)、模型编译优化、芯片专属部署全流程。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 762

变成字符串_LeetCode 87,远看是字符串其实是搜索,你能做出来吗?

本文始发于个人公众号:TechFlow,原创不易,求个关注今天是LeetCode专题第54篇文章,我们一起来看LeetCode 87题,Scramble String(爬行字符串)。这题的官方难度是Hard,通过率33%,点赞506,反对702。看起来这题难度还可以,但是反对比点赞多,其实这题质量还不错,反对比较多我猜可能是因为题意稍稍有些复杂,理解起来不太容易,编码也偏难。但是这题如果是放在正式...

weixin_39743824的博客 61

5.17华为OD机试真题 新系统 - 输出二叉树后序遍历结果 (Java/Py/C/C++/Js/Go)

5.17华为OD机试真题 新系统 - 输出二叉树后序遍历结果 (Java/Py/C/C++/Js/Go)

算法大师! 515

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

leetcode 87. 扰乱字符串

【代码】leetcode 87. 扰乱字符串。

fks143的专栏 945

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

leetcode87 扰乱字符串

leetcode87 参考方法1:动态规划 如果s1和s2的长度一致,并且所包含的字符种类,以及字符的数量一致,检查s1和s2是否和谐。 和谐: s1=l(s1) + r(s1) s2 =l(s2) + r(s2) 其中l(s1)和l(s2),r(s1)和r(s2) 以及 l(s1)和 ...

weixin_43876597的博客 182

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

LeetCode 86分割链表&87扰乱字符串

分割链表 题目描述: 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。 你应当保留两个分区中每个节点的初始相对位置。 示例: 输入: head = 1->4->3->2->5->2, x = 3 输出: 1->2->2->4->3->5 分析: 这题的话也很简单,它要求将小于x的节点放到前面,且相对位置不变。我们可以采用两个链表将其分割开来然后再合并,在具体的处理上,可以创建两个带头

bigsai 3258

力扣 87. 扰乱字符串 记忆化搜索 思维

https://leetcode-cn.com/problems/scramble-string/ 思路:先定义一种字符串之间的相似运算:如果字符串a、b长度相等且含有的字符都相同,我们认为a和b相似。显然如果s、t互为扰乱字符串,则它们一定相似。从扰乱字符串的规则可以发现,如果断点是i,那么至少满足以下两种情况的某一种: s[0…i]、t[0…i]s[0…i]、t[0…i]s[0…i]、t[0…i]相似且s[i+1…n)、t[i+1…n)s[i+1…n)、t[i+1…n)s[i+1…n)、t[i+1…

xiji333的博客 232

leetcode#87 扰乱字符串

leetcode#87 扰乱字符串 题目: 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 1、如果字符串的长度为 1 ,算法停止 2、如果字符串的长度 > 1 ,执行下述步骤: 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 x 和 y ,且满足 s = x + y 。 随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,s 可能是 s = x + y 或者 s = y + x 。 在

weixin_48673014的博客 227

LeetCode 87. 扰乱字符串

题目描述 题目链接:https://leetcode-cn.com/problems/scramble-string/ 87. 扰乱字符串 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行下述步骤: 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 x 和 y ,且满足 s = x + y 。 随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,

GHY 186

​【LeetCode每日一题】87. 扰乱字符串

【LeetCode每日一题】87. 扰乱字符串题目:使用下面描述的算法可以扰乱字符串 s 得到字符串 t :如果字符串的长度为 1 ,算法停止如果字符串的长度 > 1 ,执行下述步骤...

Francis的博客 325

​LeetCode刷题实战87: 扰乱字符串

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ...

程序IT圈 202

字符串拆开成两个_LeetCode刷题实战87: 扰乱字符串

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !今天和大家聊的问题叫做扰乱字符串,我们先来看题面:https://leetcode-cn.com/problems/scramble-string/We can scramble a string s...

weixin_39966163的博客 262
上一篇: Golang | Go语言多态的实现与interface使用
下一篇: LeetCode 89,因为题目晦涩而被点了1500+反对的搜索问题
TechFlow
博客等级 码龄7年 347粉丝 276原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值