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. Mac 配置adb环境变量(为了开Appium)亲测

    1.启动终端Terminal. 2.进入当前用户的home目录. 在命令行输入echo $HOME 3.创建.bash_profile文件. 命令行输入touch .bash_profile 4.打开 ...

  2. 自然语言20.1 WordNet介绍和使用

     https://study.163.com/provider/400000000398149/index.htm?share=2&shareId=400000000398149(欢迎关注博主 ...

  3. n个骰子可能的点数和

    让后面的点数比前面的大 package touzi; public class Touzi { public static void main(String[] args) { // TODO Aut ...

  4. 百度AI---语音识别

    题记:娱乐性的玩玩百度接口. 说实话,其接口个人觉得有点烂,重试了好几个音频文件才成功. 1.重新申请AppID.SecretKey .API Key. 链接:https://console.bce. ...

  5. 阶段3 3.SpringMVC·_04.SpringMVC返回值类型及响应数据类型_7 响应json数据之发送ajax的请求

    编写conroller的方法 @RequestBody获取请求体的内容.当前请求体传递的是json字符串. 拿到了请求的内容

  6. Spring学习之==>AOP

    一.概述 AOP(Aspect Oriented Programming)称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等,Struts2的拦截器设计就是基于A ...

  7. Android adb.exe 开发模试安装

    1.安装 adb . 让它直接能在cmd 窗口运行 下载:platform-tools  这个就行: Download SDK Platform-Tools for Windows 下载完成后直接解压 ...

  8. iOS限制输入解决方法

    关于iOS 键盘输入限制(只能输入字母,数字,禁止输入特殊符号): 方法一: 直接限制输入 - (void)viewDidLoad { [super viewDidLoad]; textField = ...

  9. phpfpm和nginx设置开机自动启动

    ## 添加执行权限 chmod a+x /etc/init.d/nginx chmod a+x /etc/init.d/php-fpm ## 加入服务 chkconfig --add nginx ch ...

  10. 基于Bootstrap 3可预览的HTML5文件上传插件

    前端常用资源地址: http://www.htmleaf.com/ http://www.htmleaf.com/html5/html5muban/201505091801.html 源代码地址 ht ...