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
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分成s11和s12,s2分成s21和s22,则有
isScramble(s11, s21) && isScramble(s12, s22)
或者
isScramble(s11, s22) && isScramble(s12, s21)
怎么分割,我们不知道,所以要试验每一个位置,只要有一个位置的分割可行,就可以返回true.
对于递归解法来讲,要剪枝才能过,剪枝的意思就是把不合理的尽早去除,不要再进入递归了。
比如:
1,长度不相等,
2,排序之后内容不相同
还有,一种能尽早得到结果,比如
s1.equals(s2)
这也没有必要进入下层递归了。
另外,我们知道,在适用的情况下,桶排是最快的排序。
public class Solution {
public boolean isScramble(String s1, String s2) {
if(s1.length() != s2.length()) return false;
if(s1.equals(s2)) return true;
int[] count = new int[26];
int len = s1.length();
for(int i=0; i<len; i++){
count[s1.charAt(i)-'a']++;
count[s2.charAt(i)-'a']--;
}
for(int i=0; i<26; i++){
if(count[i]!=0) return false;
}
for(int step=1; step<len; step++){
String s11 = s1.substring(0,step);
String s12 = s1.substring(step);
String s21 = s2.substring(0,step);
String s22 = s2.substring(step);
if(isScramble(s11,s21)&&isScramble(s12,s22)) return true;
s21 = s2.substring(0, len-step);
s22 = s2.substring(len-step);
if(isScramble(s11,s22)&&isScramble(s12,s21)) return true;
}
return false;
}
}