import java.util.Arrays;

/**
* Source : https://oj.leetcode.com/problems/scramble-string/
*
* 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.
*
*/
public class ScrambleString { /**
* s1是不是s2的一个scramblestring
* s1按照任意位置进行二分划分,一直递归下去,期间,可以交换非叶子节点的两个子节点左右顺序,一直到叶子节点
*
* 一开始想着是找到s1的所有scramblestring,然后判断s2是否在里面
* 但是其实在寻找s2的scramblestring的时候就可以和s2进行对比判断,而不需要存储所有的scramblestring
*
* 选择
* s1分割的位置,递归的进行如下判断
* s1在i左边的子串和s2在i左边的子串是scramble的,s1在i的右边的子串和s2在i右边的子串是scramble的,或者
* s1在i左边的子串和s2在i右边的子串是scramble的,s1在i的右边的子串和s2在i左边的子串是scramble的
*
* @param s1
* @param s2
*/
public boolean scramble (String s1, String s2) {
if (s1.length() != s2.length()) {
return false;
}
if (s1.length() <= 1) {
return s1.equals(s2);
}
// return recursion(s1, s2);
return recursion1(s1, s2);
} public boolean recursion (String s1, String s2) {
int len = s1.length();
if (len == 1) {
return s1.equals(s2);
}
for (int i = 1; i < len; i++) {
if ((recursion(s1.substring(0, i), s2.substring(0, i)) && recursion(s1.substring(i), s2.substring(i)))
|| (recursion(s1.substring(0,i), s2.substring(len-i)) && recursion(s1.substring(i), s2.substring(0,len-i)))) {
return true;
}
}
return false;
} /**
* 递归的时候有些分支是不必要的,可以剪裁分支
* 在递归的时候,对s1和s2进行排序,如果排序之后两个字符串不相等则不必要继续递归
*
* @param s1
* @param s2
* @return
*/
public boolean recursion1 (String s1, String s2) {
int len = s1.length();
if (len == 1) {
return s1.equals(s2);
}
char[] s1CharArr = s1.toCharArray();
Arrays.sort(s1CharArr);
String sortedS1 = new String(s1CharArr);
char[] s2CharArr = s2.toCharArray();
Arrays.sort(s2CharArr);
String sortedS2 = new String(s1CharArr);
if (!sortedS1.equals(sortedS2)) {
return false;
} for (int i = 1; i < len; i++) {
if ((recursion(s1.substring(0, i), s2.substring(0, i)) && recursion(s1.substring(i), s2.substring(i)))
|| (recursion(s1.substring(0,i), s2.substring(len-i)) && recursion(s1.substring(i), s2.substring(0,len-i)))) {
return true;
}
}
return false;
} /**
* 递归的时候会有一些重复计算,使用数组记录计算过的结果,每次递归的时候判断,如果已经计算过则直接使用计算过的结果
* 中间结果需要一个三维的boolean数组,因为,每次计算结果的变量是s1.index1,s2.index2,还有当前字符串的长度len
*
* @param s1
* @param s2
* @return
*/
public boolean scramble2 (String s1, String s2) {
if (s1.length() != s2.length()) {
return false;
}
if (s1.length() <= 1) {
return s1.equals(s2);
}
int[][][] calculated = new int[s1.length()][s2.length()][s1.length()];
for (int i = 0; i < s1.length(); i++) {
for (int j = 0; j < s2.length(); j++) {
Arrays.fill(calculated[i][j], -1);
}
}
return recursion(s1, s2);
} public boolean recursion2 (String s1, int index1, String s2, int index2, int len, int[][][] calculated) {
if (len == 1) {
return s1.charAt(index1) == s2.charAt(index2);
}
int preresult = calculated[index1][index1][len-1];
if (preresult != -1) {
return preresult == 1;
}
preresult = 0;
for (int i = 1; i < len; i++) {
if (recursion2(s1, index1, s2, index2, i, calculated)
&& recursion2(s1, index1 + 1, s2, index2 + 1, len - i, calculated)) {
preresult = 1;
break;
}
if (recursion2(s1, index1, s2, index2 + len - i, i, calculated)
&& recursion2(s1, index1 + 1, s2, index2, len - i, calculated)) {
preresult = 1;
break;
}
}
calculated[index1][index2][len-1] = preresult;
return preresult == 1;
} public static void main(String[] args) {
ScrambleString scrambleString = new ScrambleString();
System.out.println(scrambleString.scramble("great", "rgtae"));
System.out.println(scrambleString.scramble2("great", "rgtae"));
}
}

leetcode — scramble-string的更多相关文章

  1. Leetcode:Scramble String 解题报告

    Scramble String Given a string s1, we may represent it as a binary tree by partitioning it to two no ...

  2. [LeetCode] Scramble String -- 三维动态规划的范例

    (Version 0.0) 作为一个小弱,这个题目是我第一次碰到三维的动态规划.在自己做的时候意识到了所谓的scramble实际上有两种可能的类型,一类是在较低层的节点进行的两个子节点的对调,这样的情 ...

  3. [LeetCode] Scramble String 爬行字符串

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

  4. [leetcode]Scramble String @ Python

    原题地址:https://oj.leetcode.com/problems/scramble-string/ 题意: Given a string s1, we may represent it as ...

  5. [Leetcode] Scramble String

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

  6. [LeetCode] Scramble String(树的问题最易用递归)

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

  7. [Leetcode] scramble string 乱串

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

  8. [LeetCode] Scramble String 字符串 dp

    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

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

  10. 【leetcode】Scramble String

    Scramble String Given a string s1, we may represent it as a binary tree by partitioning it to two no ...

随机推荐

  1. 勾勾街——一个专注于免越狱免签名的苹果ios APP打包生成的网站

    自涛舅舅研发的“苹果ios APP自助生成系统”上线以来,每天都有大量的用户注册和生成免越狱app,为什么? 因为我们有明显的技术优势,APP不需要上架appstore, 生成APP又不需要企业签名证 ...

  2. 2018-2019-2 网络对抗技术 20162329 Exp3 免杀原理与实践

    目录 免杀原理与实践 一.基础问题回答 1.杀软是如何检测出恶意代码的? 2.免杀是做什么? 3.免杀的基本方法有哪些? 二.实验内容 1. 正确使用msf编码器 2. msfvenom生成如jar之 ...

  3. Hadoop下WordCount程序

    一.前言 在之前我们已经在 CenOS6.5 下搭建好了 Hadoop2.x 的开发环境.既然环境已经搭建好了,那么现在我们就应该来干点正事嘛!比如来一个Hadoop世界的HelloWorld,也就是 ...

  4. 字符串转义为HTML

    有时候后台返回的数据中有字符串,并需要将字符串转化为HTML,下面封装了一个方法,如下 // html转义 function htmlspecialchars_decode(string, quote ...

  5. PHP 经典有趣的算法收集(面试题)

    1.一群猴子排成一圈,按1,2,…,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去…,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫 ...

  6. SpringBoot报错:The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone

    解决方法: 在数据库连接url配置后边加&serverTimezone=GMT%2B8 例: jdbc:mysql://127.0.0.1:3306/test改为jdbc:mysql://12 ...

  7. 【高并发架构】Redis特点及构件模型

    数据结构 redis 相比 memcached 来说,拥有更多的数据结构,能支持更丰富的数据操作.如果需要缓存能够支持更复杂的结构和操作, redis 会是不错的选择. redis 主要有以下几种数据 ...

  8. centos7 mysql自动备份

    MySQL自动备份shell脚本   在数据库的日常维护工作中,除了保证业务的正常运行以外,就是要对数据库进行备份,以免造成数据库的丢失,从而给企业带来重大经济损失.通常备份可以按照备份时数据库状态分 ...

  9. [Zephyr] 1、在linux上安装Zephyr-OS并跑DEMO

    星期五, 14. 九月 2018 02:18上午 - BEAUTIFULZZZZ 0) 前言 Zephyr™项目是一个采用Apache 2.0协议许可,Linux基金会托管的协作项目.为所有资源受限设 ...

  10. C++或C#调用外部exe的分析

    假如有个外部程序名为A.exe,放在目录E:\temp\下,然后我们用C++或者C#写一个程序调用这个A.exe的话(假设这个调用者所在的路径在D:\invoke),通常会采用下面的代码: // C# ...