题目:
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.
题意:
给定字符串s1 ,我们可以用二叉树的形式,递归地将其分为两个不为空的子集。
下面就是s1 = "great"
的一种可能的表示方法:
great
/ \
gr eat
/ \ / \
g r e at
/ \
a t
在拼凑字符串的过程中,我们可以选择任意的非叶子节点并交换它的两个孩子。
比如说,如果我们选择节点 "gr"
并交换它的两个孩子,这将产生一个拼凑的字符"rgeat"
.
rgeat / \ rg eat / \ / \ r g e at / \ a t我们将
"rgeat"称为"great"
的相似字符串。
类似地,如果我们继续交换孩子节点
"eat"
and "at",
这将产生一个拼凑字符
"rgtae"
.
rgtae / \ rg tae / \ / \ r g ta e / \ t a我们将"rgtae"称为"great"的相似字符串。
给定两个长度相等的字符串s1和s2,判定s2是否为s1的相似字符串。
算法分析:
* 对付复杂问题的方法是从简单的特例来思考,从而找出规律。
* 先考察简单情况:
* 字符串长度为1:很明显,两个字符串必须完全相同才可以。
* 字符串长度为2:当s1="ab", s2只有"ab"或者"ba"才可以。
* 对于任意长度的字符串,我们可以把字符串s1分为a1,b1两个部分,s2分为a2,b2两个部分,满足((a1~a2) && (b1~b2))或者 ((a1~b2) && (a2~b1))
* 如此,我们找到了解决问题的思路。首先我们尝试用递归来写。
(递归):
* 两个字符串的相似的必备条件是含有相同的字符集。简单的做法是把两个字符串的字符排序后,然后比较是否相同。
* 加上这个检查就可以大大的减少递归次数。
AC代码:
<span style="font-family:Microsoft YaHei;font-size:12px;">public class Solution
{
public boolean isScramble(String s1, String s2)
{
int l1 = s1.length();
int l2 = s2.length();
if(l1!=l2)
{
return false;
}
if(l1==0)
{
return true;
}
char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();
if(l1==1)
{
return c1[0]==c2[0];
}
Arrays.sort(c1);
Arrays.sort(c2);
for(int i=0;i<l1;++i)
{
if(c1[i]!=c2[i])
return false;
}
boolean result = false;
for(int i=1;i<l1 && !result;++i)
{
String s11 = s1.substring(0,i);
String s12 = s1.substring(i);
String s21 = s2.substring(0,i);
String s22 = s2.substring(i);
result = isScramble(s11,s21) && isScramble(s12,s22);
if(!result)
{
String s31 = s2.substring(0,l1-i);
String s32 = s2.substring(l1-i);
result = isScramble(s11,s32) && isScramble(s12,s31);
}
}
return result;
}
}</span>