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: 递归Recursion

解法2: 动态规划Dynamic Programming

Java:

public class Solution {
public boolean isScramble(String s1, String s2) {
if (s1.equals(s2)) return true; int[] letters = new int[26];
for (int i=0; i<s1.length(); i++) {
letters[s1.charAt(i)-'a']++;
letters[s2.charAt(i)-'a']--;
}
for (int i=0; i<26; i++) if (letters[i]!=0) return false; for (int i=1; i<s1.length(); i++) {
if (isScramble(s1.substring(0,i), s2.substring(0,i))
&& isScramble(s1.substring(i), s2.substring(i))) return true;
if (isScramble(s1.substring(0,i), s2.substring(s2.length()-i))
&& isScramble(s1.substring(i), s2.substring(0,s2.length()-i))) return true;
}
return false;
}
}

Python:

# Time:  O(n^4)
# Space: O(n^3)
class Solution(object):
# @return a boolean
def isScramble(self, s1, s2):
if not s1 or not s2 or len(s1) != len(s2):
return False
if s1 == s2:
return True
result = [[[False for j in xrange(len(s2))] for i in xrange(len(s1))] for n in xrange(len(s1) + 1)]
for i in xrange(len(s1)):
for j in xrange(len(s2)):
if s1[i] == s2[j]:
result[1][i][j] = True for n in xrange(2, len(s1) + 1):
for i in xrange(len(s1) - n + 1):
for j in xrange(len(s2) - n + 1):
for k in xrange(1, n):
if result[k][i][j] and result[n - k][i + k][j + k] or\
result[k][i][j + n - k] and result[n - k][i + k][j]:
result[n][i][j] = True
break return result[n][0][0]  

C++: Recursion

class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1==s2)
return true; int len = s1.length();
int count[26] = {0};
for(int i=0; i<len; i++)
{
count[s1[i]-'a']++;
count[s2[i]-'a']--;
} for(int i=0; i<26; i++)
{
if(count[i]!=0)
return false;
} for(int i=1; i<=len-1; i++)
{
if( isScramble(s1.substr(0,i), s2.substr(0,i)) && isScramble(s1.substr(i), s2.substr(i)))
return true;
if( isScramble(s1.substr(0,i), s2.substr(len-i)) && isScramble(s1.substr(i), s2.substr(0,len-i)))
return true;
}
return false;
}
};

C++: Recursion

class Solution {
public:
bool isScramble(string s1, string s2) {
if (s1.size() != s2.size()) return false;
if (s1 == s2) return true;
string str1 = s1, str2 = s2;
sort(str1.begin(), str1.end());
sort(str2.begin(), str2.end());
if (str1 != str2) return false;
for (int i = 1; i < s1.size(); ++i) {
string s11 = s1.substr(0, i);
string s12 = s1.substr(i);
string s21 = s2.substr(0, i);
string s22 = s2.substr(i);
if (isScramble(s11, s21) && isScramble(s12, s22)) return true;
s21 = s2.substr(s1.size() - i);
s22 = s2.substr(0, s1.size() - i);
if (isScramble(s11, s21) && isScramble(s12, s22)) return true;
}
return false;
}
};  

C++: DP

class Solution {
public:
bool isScramble(string s1, string s2) {
if (s1.size() != s2.size()) return false;
if (s1 == s2) return true;
int n = s1.size();
vector<vector<vector<bool> > > dp (n, vector<vector<bool> >(n, vector<bool>(n + 1, false)));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
dp[i][j][1] = s1[i] == s2[j];
}
}
for (int len = 2; len <= n; ++len) {
for (int i = 0; i <= n - len; ++i) {
for (int j = 0; j <= n - len; ++j) {
for (int k = 1; k < len; ++k) {
if ((dp[i][j][k] && dp[i + k][j + k][len - k]) || (dp[i + k][j][len - k] && dp[i][j + len - k][k])) {
dp[i][j][len] = true;
}
}
}
}
}
return dp[0][0][n];
}
};

C++:

class Solution {
public:
bool isScramble(string s1, string s2) {
if (s1.size() != s2.size()) return false;
if (s1 == s2) return true;
int n = s1.size();
vector<vector<vector<bool> > > dp (n, vector<vector<bool> >(n, vector<bool>(n + 1, false)));
for (int i = n - 1; i >= 0; --i) {
for (int j = n - 1; j >= 0; --j) {
for (int k = 1; k <= n - max(i, j); ++k) {
if (s1.substr(i, k) == s2.substr(j, k)) {
dp[i][j][k] = true;
} else {
for (int t = 1; t < k; ++t) {
if ((dp[i][j][t] && dp[i + t][j + t][k - t]) || (dp[i][j + k - t][t] && dp[i + t][j][k - t])) {
dp[i][j][k] = true;
break;
}
}
}
}
}
}
return dp[0][0][n];
}
};

  

  

  

All LeetCode Questions List 题目汇总

[LeetCode] 87. Scramble String 爬行字符串的更多相关文章

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

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

  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. [LintCode] Scramble String 爬行字符串

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

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

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

  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 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

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

随机推荐

  1. web程序防止攻击的一些资料——整理

    地址:https://docs.microsoft.com/en-us/previous-versions/aspnet/a2a4yykt(v=vs.100)?redirectedfrom=MSDN ...

  2. Cisco网络模拟器踩坑记录

    1.在我们新建一个拓扑图的时候,选择设备之间的连线种类有时会导致线路不通的情况(两个端口上为红色点)这时候建议拆除这条线后选择闪电标记 的万能线帮助我们自动创建连线(这时就能根据它显示的线条种类得知应 ...

  3. ACAG 0x02-8 非递归实现组合型枚举

    ACAG 0x02-8 非递归实现组合型枚举 之所以专门来写这道题的博客,是因为感觉从最根本处了解到了递归的机器实现. 主要的就是两个指令--Call和Ret. Call指令会将返回地址入栈(系统栈) ...

  4. AT2000 Leftmost Ball

    设\(f[i][j]\)表示当前有\(i\)个白球,一共放完了\(j\)种球 显然有\(j <= i\) 对于每个状态目前已经放下去的球是固定了的,那么考虑转移 放白球 从\(f[i - 1][ ...

  5. BZOJ-1975: 魔法猪学院 (K短路:A*+SPFA)

    题意:有N种化学元素,有M种转化关系,(u,v,L)表示化学物质由u变为v需要L能量,现在你有E能量,问最多有多少种不同的途径,使得1转为为N,且总能量不超过E. 思路:可以转为为带权有向图,即是求前 ...

  6. djiango-异步发送邮件--celery

    安装 pip install celery==4.2.0 # celery4.x支持django1.11以上版本 试了好几个版本 就4.2.0能发送成功 1.项目目录里新建一个celery的包cele ...

  7. fastjson<=1.2.47反序列化RCE漏洞

    介绍:fastjson是一个Java语言编写的高性能功能完善的JSON库. 漏洞原因:fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并通过json来填充其属性 ...

  8. Django API接口FK ManyTo Many 模板

    Url from django.contrib import admin from django.urls import path, re_path from django.urls import i ...

  9. 使用docker来创建一个etcd集群

    docker run -d --name etcd1 --network etcdnet --ip 172.25.0.101 -p 23791:2379 -e ETCDCTL_API=3 -v /ro ...

  10. python中序列的操作

    Python中的序列操作 可变对象:列表.字典.集合 不可变对象:数值.字符串.元组.forzenset 1.序列的通用操作 (1)测试元素是否存在 x in S和x not in S,返回True或 ...