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

Below is one possible representation of s1 = "great":

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

To scramble the string, we may choose any non-leaf node and swap its two children.

For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat".

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

We say that "rgeat" is a scrambled string of "great".

Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae".

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

We say that "rgtae" is a scrambled string of "great".

Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.

Example 1:

Input: s1 = "great", s2 = "rgeat"
Output: true

Example 2:

Input: s1 = "abcde", s2 = "caebd"
Output: false

思路:对付复杂问题的方法是从简单的特例来思考。简单情况:

  1. 如果字符串长度为1,那么必须两个字符串完全相同;
  2. 如果字符串长度为2,例如s1='ab',则s2='ab'或s2='ba'才行
  3. 如果字符串任意长度,那么可以把s1分为a1, b1两部分,s2分为a2,b2两部分。需要满足:((a1=a2)&&(b1=b2)) || ((a1=b2)&&(a2=b1)) =>可用递归
class Solution {
public boolean isScramble(String s1, String s2) {
if(s1.length()==1) return s1.equals(s2); String s11;
String s12;
String s21;
String s22;
for(int i = 1; i <= s1.length(); i++){
s11 = s1.substring(0, i);
s12 = s1.substring(i);
s21 = s2.substring(0,i);
s22 = s2.substring(i);
if(isScramble(s11,s21) && isScramble(s12,s22)) return true;
if(isScramble(s11,s22) && isScramble(s12,s21)) return true;
}
return false;
}
}

Result: Time Limit Exceeded

解决方法:动态规划。三维状态dp[i][j][k],前两维分别表示s1和s2的下标起始位置,k表示子串的长度。dp[i][j][k]=true表示s1(i, i+k-1)和s2(j, j+k-1)是scramble。

结合递归法中的逻辑,dp[i][j][k]=true的条件是s1(i, i+split-1)=s2(j, j+split-1) && s1(i+split, i+k-1) = s2(j+split, j+k-1) 或者 s1(i, i+split-1)=s2(j+k-split, j+k-1) && s1(i+split, i+k-1) = s2(j, j+k-split-1)

所以状态转移方程是:如果dp[i][j][split] = true && dp[i+split][j+split][k-split] = true 或者 dp[i][j+k-split][split]=true && dp[i+split][j][k-split]=true,那么dp[i][j][k]=true

初始状态:当k=1的时候dp[i][j][1]=true的条件是s1(i)=s2(j)

class Solution {
public boolean isScramble(String s1, String s2) {
if(s1.length()== 0 || s1.equals(s2)) return true; boolean dp[][][] = new boolean[s1.length()][s1.length()][s1.length()+1]; //initial state
for(int i = 0; i < s1.length(); i++){
for(int j = 0; j < s2.length(); j++){
dp[i][j][1] = s1.charAt(i)==s2.charAt(j);
}
} //state transfer
for(int k = 2; k <= s1.length(); k++){
for(int i = 0; i+k-1 < s1.length(); i++){
for(int j = 0; j+k-1 < s1.length(); j++){
for(int split = 1; split < k; split++){
//如果dp[i][j][split] = true && dp[i+split][j+split][k-split] = true 或者 dp[i][j+k-split][split]=true && dp[i+split][j][k-split]=true,那么dp[i][j][k]=true
if((dp[i][j][split] && dp[i+split][j+split][k-split]) || (dp[i][j+k-split][split] && dp[i+split][j][k-split])){
dp[i][j][k] = true;
break;
}
}
}
}
}
return dp[0][0][s1.length()];
}
}

87. Scramble String (Java)的更多相关文章

  1. 【一天一道LeetCode】#87. Scramble String

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  2. [leetcode]87. Scramble String字符串树形颠倒匹配

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

  3. [leetcode] 87. Scramble String (Hard)

    题意: 判断两个字符串是否互为Scramble字符串,而互为Scramble字符串的定义: 字符串看作是父节点,从字符串某一处切开,生成的两个子串分别是父串的左右子树,再对切开生成的两个子串继续切开, ...

  4. 87. Scramble String

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

  5. [LeetCode] 87. Scramble String 搅乱字符串

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

  6. [LeetCode] 87. Scramble String 爬行字符串

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

  7. Leetcode#87 Scramble String

    原题地址 两个字符串满足什么条件才称得上是scramble的呢? 如果s1和s2的长度等于1,显然只有s1=s2时才是scramble关系. 如果s1和s2的长度大于1,那么就对s1和s2进行分割,划 ...

  8. leetcode@ [87] Scramble String (Dynamic Programming)

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

  9. 【LeetCode】87. Scramble String

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

随机推荐

  1. LC 965. Univalued Binary Tree

    A binary tree is univalued if every node in the tree has the same value. Return true if and only if ...

  2. 网络通信框架之okHttpUtils

    okHttpUtils封装库志支持: 一般的get请求 一般的post请求 基于Http的文件上传 文件下载 上传下载的进度回调 加载图片 支持请求回调,直接返回对象.对象集合 支持session的保 ...

  3. distinct 与group by 去重

    mysql中常用去重复数据的方法是使用 distinct  或者group by ,以上2种均能实现,但2者也有不同的地方. distinct 特点: 如:select  distinct   nam ...

  4. DELPHI 通用的数据记录复制过程

    //表名,关键字段名,单条内容的SQL语句,产生新记录的值 function Tfrmdmmain.CopyTbale(const tablename, fileldname, swhere, new ...

  5. yum安装epel源

    国内yum源的安装(163,阿里云,epel)   国内yum源的安装(163,阿里云,epel) ----阿里云镜像源 1.备份 mv /etc/yum.repos.d/CentOS-Base.re ...

  6. [转] 运维知识体系 -v3.1 作者:赵舜东(赵班长)转载请注明来自于-新运维社区:https://www.unixhot.com

    [From]https://www.unixhot.com/page/ops [运维知识体系]-v3.1 作者:赵舜东(赵班长) (转载请注明来自于-新运维社区:https://www.unixhot ...

  7. CommonJS、AMD、CMD、ES6——JavaScript模块化

    CommonJS规范:Node AMD规范:RequireJS CMD规范:SeaJS ES6模块

  8. gitlab 数据目录迁移

    一般情况下,采用gitlab作为版本管理工具,内网环境需要搭建gitlab服务器,安装好gitlab应用之后,就开始使用,但是随着时间的推移,发现gitlab的repository会越来越大.一般,从 ...

  9. 蓝鲸 修改主机名重装后初始化不了cmdb安装不了job + 数据采集流程

    1.表象:在部署蓝鲸JOB过程中需要进行RabbitMQ的安装,数据初始化,激活步骤,此问题多发生在此过程 [ root@rbtnodel install)# ./bkcec initdata rab ...

  10. ASP.NET Core WebApi使用Swagger生成API说明文档【xml注释版】

    ⒈新建ASP.NET Core WebAPi项目 ⒉添加 NuGet 包 Install-Package Swashbuckle.AspNetCore ⒊Startup中配置 using System ...