扰乱字符串

给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树。

下图是字符串 s1 = "great" 的一种可能的表示形式。

在扰乱这个字符串的过程中,我们可以挑选任何一个非叶节点,然后交换它的两个子节点。

例如,如果我们挑选非叶节点 "gr" ,交换它的两个子节点,将会产生扰乱字符串 "rgeat" 。

我们将 "rgeat" 称作 "great" 的一个扰乱字符串。

同样地,如果我们继续将其节点 "eat" 和 "at" 进行交换,将会产生另一个新的扰乱字符串 "rgtae" 。

我们将 "rgtae" 称作 "great" 的一个扰乱字符串。

给出两个长度相等的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。

示例 1:

输入: s1 = "great", s2 = "rgeat"

输出: true

示例 2:

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

输出: false

【分析】

题意在于判断一个字符串是否为另一个字符串"乱序"得到,这种乱序采用的方式是将一个字符串从某个位置"割开",形成两个子串,然后对两个子串进行同样的"割开"操作,直到到达叶子节点,无法再分割。然后对非叶子节点的左右孩子节点进行交换,最后重新从左至右组合形成新的字符串,由于这个过程中存在字符位置的变化,因此,原来的字符串顺序可能会被打乱,当然也可能没有(同一个非叶子节点的左右孩子交换0次或偶数次,就无变化)。需要注意的点:

1、原字符串每次被割开的位置并不确定可能为[1,s.size()-1],所以必然需要遍历所有可能割开的位置;

2、原字符串从第i个位置被割开(i在区间[1,s.size()-1]),形成的两个子串s.substr(0,i)和s.substr(i,s.size()-i),如果这两个子串不全为空,则它们的母串(这里指原字符串)就是所谓的非叶子节点,这两个子串可以左右交换(按照二叉树的展开方式);对于两个子串,可继续割裂,直到形成叶子节点。

3、可以想见,原字符串对应的"乱序"串s1,定然满足如下规律:如果将"乱序"串同样从第i个位置割开,他同样可以形成两个子串,s1.substr(0,i)和s1.substr(i,s1.size()-i),并且满足:

s1.substr(0,i)是s.substr(0,i)的"乱序"且s1.substr(i,s1.size()-i)是s.substr(i,s.size()-i)的""乱序

或者(因为左右交换的原因)

s1.substr(0,i)是s.substr(s.size()-i)的"乱序"且s1.substr(i)是s.substr(0,s.size()-i)的"乱序"

4、如上分析,我们就可以将大问题分解成小问题,通过递归调用,便可以判断两个字符串是否互为"乱序",还需注意一个问题就是"剪枝"操作,二叉树形式分解,层次很深,每一层都应满足(3)中的两种可能之一,如果不满足便不再继续下一层,直接返回false,这便是一种剪枝操作,可以极大的提升效率。

5、"剪枝"约束,若两个字符串s1和s2互为"乱序",需满足s1和s2包含的字符及数量应完全相同,如果不同,则不可能构成"乱序",因此这个条件可作为剪枝条件;

6、两个工具:判断两个字符串是否包含完全相同的字母,用到了"哈希表";割裂形成子串用到STL函数:substr(i,n);表示获得字符串从第i个位置开始的n个字符,如果n空缺,默认为到字符串末尾。

 class Solution{
public:
bool isScramble(string s1,string s2){
if(s1.size()!=s2.size()) return false;
if(s1==s2) return true;
vector<int> hash(26,0);
for(int i=0;i<s1.size();i++)
hash.at(s1[i]-'a')++;
for(int j=0;j<s2.size();j++)
hash.at(s2[j]-'a')--;
for(int k=0;k<26;k++){
if(hash.at(k)!=0)
return false;
}
for(int i=1;i<s1.size();i++){
if((isScramble(s1.substr(0,i),s2.substr(0,i))&&isScramble(s1.substr(i,s1.size()-i),s2.substr(i,s1.size()-i)))
||(isScramble(s1.substr(0,i),s2.substr(s1.size()-i))&& isScramble(s1.substr(i),s2.substr(0,s1.size()-i))))
return true;
}
return false;
}
};

Leetcode 87.扰乱字符串的更多相关文章

  1. Java实现 LeetCode 87 扰乱字符串

    87. 扰乱字符串 给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树. 下图是字符串 s1 = "great" 的一种可能的表示形式. grea ...

  2. C#LeetCode刷题-字符串

    字符串篇 # 题名 刷题 通过率 难度 3 无重复字符的最长子串   24.6% 中等 5 最长回文子串   22.4% 中等 6 Z字形变换   35.8% 中等 8 字符串转整数 (atoi)   ...

  3. LeetCode(87):扰乱字符串

    Hard! 题目描述: 给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树. 下图是字符串 s1 = "great" 的一种可能的表示形式. gr ...

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

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第54篇文章,我们一起来看LeetCode 87题,Scramble String(爬行字符串). 这题的官方难度 ...

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

    [python]Leetcode每日一题-扰乱字符串 [题目描述] 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行 ...

  6. [Swift]LeetCode87. 扰乱字符串 | Scramble String

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...

  7. 087 Scramble String 扰乱字符串

    给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树.下图是字符串s1 = "great"的一种可能的表示形式.    great   /    \ ...

  8. C#版(击败100.00%的提交) - Leetcode 151. 翻转字符串里的单词 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...

  9. C#版(击败97.76%的提交) - Leetcode 557. 反转字符串中的单词 III - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. Leetcod ...

随机推荐

  1. Rails5入门

    更新: 2017/05/29 更新: 2017/09/07 补充对ruby自身的扩张的放置位置  配置文件位置  /config/routes.rb  最简单的定义方法  get ('hello/in ...

  2. bzoj 3733: [Pa2013]Iloczyn【dfs】

    参考:http://www.cnblogs.com/clrs97/p/5125976.html 瞎搞约数失败...滚去搜索 dfs(x,y,z) 表示当前可选第x到第m个约数,还要选y个约数,已有z的 ...

  3. 清理TIME_WAIT

    cat >> /etc/sysctl.conf << EOFnet.ipv4.tcp_tw_reuse=1net.ipv4.tcp_tw_recycle=1net.ipv4.t ...

  4. 洛谷 P3437 [POI2006]TET-Tetris 3D

    二维线段树区间更新啊 树套树的外层树,如果是线段树的话一般似乎不能打标记?(毕竟标记不好下传) 然而起码对于这题是可以的...对于外层线段树,每个节点放两个内层线段树dat和setv,分别是得到的值和 ...

  5. 题解报告:hdu 1010 Tempter of the Bone

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 Problem Description The doggie found a bone in a ...

  6. SAS进阶《深入分析SAS》之数据汇总和展现

    SAS进阶<深入分析SAS>之数据汇总和展现 1. 通过Print过程制作报表 proc print <data=数据集>; run; 选项: obs=修改观测序号列标签 no ...

  7. 联想 Vibe Shot(Z90-7) 免recovery 获取ROOT权限 救砖 VIBEUI V3.1_1625

    >>>重点介绍<<< 第一:本刷机包可卡刷可线刷,刷机包比较大的原因是采用同时兼容卡刷和线刷的格式,所以比较大第二:[卡刷方法]卡刷不要解压刷机包,直接传入手机后用 ...

  8. The user specified as a definer ('root'@'%') does not exist 解决方法

    mysql> grant all privileges on *.* to root@"%" identified by "."; Query OK, r ...

  9. Java中PrintStream(打印输出流)

    Java中PrintStream(打印输出流)   PrintStream 是打印输出流,它继承于FilterOutputStream. PrintStream 是用来装饰其它输出流.它能为其他输出流 ...

  10. centos7服务器安装fail2ban配合Firewalld防护墙防止SSH爆破与防护网站CC攻击

    centos7服务器安装fail2ban配合Firewalld防护墙防止SSH爆破与防护网站CC攻击 1.检查firewalld是否启用 #如果您已经安装iptables建议先关闭 service i ...