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 tFor 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 tWe 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 aWe 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; } }