一个字符串可以分解成多种二叉树结构。如果 str 长度为 1 ,认为不可分解。如果 str 长度为 N(N > 1),左部分长度可 以为 1 ~ N - 1,剩下的为右部分的长度。左部分和右部分都可以按照同样的逻辑,继续分解。形成的所有结构都是 str 的二叉树结构。

比如,字符串“abcd”,可以分解成一下五种结构:

任何一个str的二叉树结构中,如果两个节点有共同的父节点,那么这两个节点可以交换位

置,这两个节点叫作一个交换组。一个结构会有很多交换组,每个交换组都可以选择进行交

换或者不交换,最终形成一个新的结构,这个新结构所代表的字符串叫作 str的旋变字符串。

比如, 在上面的结构五中,交换组有a和b、ab和c、abc和d。如果让a和b的组交换;让ab和

c的组不交 换;让abc和d的组交换,形成的结构如图


这个新结构所代表的字符串为"dbac",叫作"abcd"的旋变字符串。也就是说,一个字符串

str的旋变字符串是非常多的,str 可以形成很多种结构,每一种结构都有很多交换组,每

一个交换组都可以选择交换或者不交换,形成的每一个新的字符串都叫 str的旋变字符串。

给定两个字符串str1和str2,判断str2是不是str1的旋变字符串。

解法一:暴力递归

分析:

str2 是 str1 的旋变字符串必须满足一下条件:

  1. len( str1 ) == len( str2 )
  2. str1 和 str2 的字符种类必须相同。
  3. str1 和 str2 的每种字符的个数必须相同。

根据以上三个条件,我们可以写一个过滤器。

def valid(str1, str2):    if len(str1) != len(str2): return False

    map1 = {}    for i in range(len(str1)):        map1[str1[i]] = map1.get(str1[i], 0) + 1

    for i in range(len(str2)):        num = map1.get(str2[i], 0)        num -= 1        if num < 0: return False        map1[str2[i]] = num

    return True

尝试模型是:范围上尝试

判断 和 是不是互为旋变字符串。

此种尝试方案:有四个参数:

根据上边过滤器的条件,我们知道 和 要是互为旋变字符串,长度必须相等。因此,我们可以将将参数压缩成三个: ,k 是str1 的长度。

表示 判断 和 是不是互为旋变字符串。

最终返回结果:f( 0, 0, len(arr) - 1)

Base case

  • 如果 k ==1 只有一个字符,只要

如下图:第一刀在 str 中每一个位置进行尝试,每一刀分隔出的两部分进行比对(调用子过程),需要交换后再比对(调用子过程)。

只要有一部分是互为旋变字符串,就返回true。否则继续尝试第二刀,第三刀...

def is_scramble(str1, str2):    if not str1 and not str2: return True    if (not str1 and str2) or (str1 and not str2): return False    if str1 == str2: return True    if not valid(str1, str2): return False    return f(str1, str2, 0, 0, len(str1))

def f(str1, str2, l1, l2, k):    if k == 1: return str1[l1] == str2[l2]

    for i in range(1, k):        res = (f(str1, str2, l1, l2, i) and f(str1, str2, l1 + i, l2 + i, k - i)) or \              (f(str1, str2, l1, l2 + k - i, i) and f(str1, str2, l1 + i, l2, k - i))        if res: return True

    return False

解法二:动态规划

本地依赖关系不好梳理,但是原问题的 k ,和依赖的子问题的 k’ 的关系是:k‘ < k。所以在填充当前层数据时,只依赖下边层的数据,不依赖本次层数据。dp 表填充顺序,从下向上填写。

base case 是 k ==1 时,


def is_scramble2(str1, str2):    if not str1 and not str2: return True    if (not str1 and str2) or (str1 and not str2): return False    if str1 == str2: return True    if not valid(str1, str2): return False

    n = len(str1)    dp = []    for i in range(n + 1):        dp.append([[False] * n for _ in range(n)])

    for l1 in range(n):        for l2 in range(n):            dp[1][l1][l2] = str1[l1] == str2[l2]

    for k in range(2, n + 1):        for l1 in range(0, n - k + 1):            for l2 in range(0, n - k + 1):                for i in range(1, k):                    if (dp[i][l1][l2] and dp[k - i][l1 + i][l2 + i]) or \                            (dp[i][l1][l2 + k - i] and dp[k - i][l1 + i][l2]):                        dp[k][l1][l2] = True                        break

    return dp[n][0][0]

本文由 mdnice 多平台发布

【每日一题】旋变字符串相关推荐

  1. AcWing每日一题 3333.K-优字符串(水题)

    K-优字符串 原题链接 Charles 将一个字符串的优良分数定义为,在 1≤i≤N/2 的范围内,满足 Si≠SN−i+1 的 i 的数量(索引从 1 开始). 例如,字符串 CABABC 的优良分 ...

  2. #我爱cf之每日一题——辣鸡字符串 02

    Codeforces Round #478 (Div. 2) A. Aramic Script 思路:很明显...就是由字母构成不同的字符串的个数.问题是怎么表示出这一层意思.题解告诉我们经验告诉我们 ...

  3. [每日一题] 73. 电话号码(字符串、set)

    1. 题目来源 链接:电话号码 来源:牛客网 2. 题目说明 上图是一个电话的九宫格,如你所见一个数字对应一些字母,因此在国外企业喜欢把电话号码设计成与自己公司名字相对应.例如公司的Help Desk ...

  4. 牛客 旋变字符串问题

    题目链接:https://www.nowcoder.com/practice/3f3da7624dfc4cb5b3959c1bb54561dc?tpId=101&tqId=33201& ...

  5. 【每日一题】快速检索

    [每日一题]快速检索 1.笔试-选择题   [笔试-选择题] 2.有关字符串   [每日一题]删除公共字符   [每日一题]字符串筛选-去除所有相同的字符   [每日一题]倒置字符串-巧用cin输入流 ...

  6. 每日一题(字符串拆分)

    前言:为了让小伙伴更方便的学习编程语言,小白每天都会分享一道编程题.小白也创建了一个微信公众号,会同步更新题目和相关的视觉领域的知识,如果小伙伴不方便在网页上阅读文章,可以关注微信公众号"小 ...

  7. 【解题报告】Leecode 438. 找到字符串中所有字母异位词——Leecode每日一题系列

    今天是坚持每日一题打卡的第二十七天 题目链接:https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/ 题解汇总:https:// ...

  8. 【解题报告】Leecode 859. 亲密字符串——Leecode每日一题系列

    今天是坚持每日一题打卡的第二十四天 题目链接:https://leetcode-cn.com/problems/buddy-strings/ 题解汇总:https://zhanglong.blog.c ...

  9. 【JAVA】交错字符串——力扣每日一题(六)(2020.07.18)

    目录 题目:97. 交错字符串 思路 如果你从本文中学习到丝毫知识,那么请您点点关注.点赞.评论和收藏 大家好,我是爱做梦的鱼,我是东北大学大数据实验班大三的小菜鸡,非常渴望优秀,羡慕优秀的人,个人博 ...

最新文章

  1. 在redhat6.4下安装 Oracle® Database 11g Release 2
  2. python json库安装_win 安装python的cjson库
  3. 提高抗打击能力_如果提高心理抗打击能力?
  4. office 2010中自带的 微软拼音输入法2010卸载
  5. 最优资产组合步骤_重新设计投资组合网站之前,请按照以下5个步骤进行操作
  6. 栈中pop和top的区别是什么呢?用队列实现一个栈,Python语言
  7. sql server一个查询语句引发的死锁
  8. 智能优化算法:头脑风暴优化算法-附代码
  9. Meego的N9发布
  10. 电脑录屏的html文件,怎样用电脑录制网页上的视频? 屏幕录像的实用方法
  11. 主板24pin接口详图_24Pin接口再见!华擎推出首款ATX12VO标准的Z490主板
  12. C#创建,调用WebS'ervice
  13. PS使用技巧(三) 吸管工具I
  14. Cosy主题3.0使用教程
  15. 在linux中使用tcpdump命令 – 监听网络流量
  16. 提升项目经理谈话能力的十个实用技巧
  17. 5.分别画出下列二次曲面
  18. ES 查询一,基于URL 的查询
  19. Oracle 表字段的创建、删除、修改、查询
  20. 解决WORD “未找到引用源”问题

热门文章

  1. 水泵控制(循环右移指令).mwp
  2. 出现net::ERR_CONNECTION_REFUSED问题,前端优化
  3. I-PEX线束加工 LVDS CABLE液晶屏线 笔记本驱屏线 测试线
  4. Win10桌面图标显示不正常变成了白色方框怎么办
  5. bigquant的策略代码
  6. 如何使用PICO示波器搭配软件实现采集、记录及回放波形功能
  7. 中国信通院发布“2022人工智能十大关键词”
  8. 人生,这道题,每个人都有每个人的答案
  9. 用机器学习提升WebRTC视频质量评估的正确姿势
  10. C/C++ plog日志简单用法