-
Notifications
You must be signed in to change notification settings - Fork 0
87. 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.
##Approach 1: recursion 解题思路为recursion。
对于两个string s1和s2,若它们是scramble string,则在其中找一个断点i,满足:
(isScramble(s1[0:i], s2[0:i]) && isScramble(s1[i:],s2[i:]))
|| (isScramble(s1[0:i], s2[s2.len-i:]) && isScramble(s1[i:],s2[0,s2.len-i]))
这个过程可以一直递归下去。
public class Solution {
public boolean isScramble(String s1, String s2) {
if(s1 == null || s2 == null || s1.length() != s2.length()) return false;
if(s1.equals("")) return false;
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;
}
}##Approach 2: Dynamic Programming
public class Solution {
public boolean isScramble(String s1, String s2) {
int len = s1.length();
if(len!=s2.length()) return false;
if(len==0) return true;
boolean[][][] isScr = new boolean[len][len][len];
for(int i = 0; i < len; i++) { //length of current substring, 0 means length==1
for(int j = 0; j + i < len; j++) { //start point of current substring at s1.
for(int k = 0; k + i < len; k++) { //start point of current substring at s2.
if(i==0) isScr[i][j][k] = s1.charAt(j)==s2.charAt(k);
for(int m = 0; m < i; m++) {
if(isScr[m][j][k] && isScr[i-(m+1)][j+m+1][k+m+1]) isScr[i][j][k] = true;
else if(isScr[m][j][k+i-m] && isScr[i-(m+1)][j+m+1][k]) isScr[i][j][k] = true;
}
}
}
}
return isScr[len-1][0][0];
}
}