2种思路:
1、递归+剪枝
2、dp
思路一、递归判断
S1的左子串L和S2的右子串 && S1的右子串和S2的左子串 是否是Scramble String!! 或者
S1的左子串L和S2的左子串 && S1的右子串和S2的右子串 是否是Scramble String!!
如果是,则return true!!!
终止条件: 当len = 1时
剪枝:每次判断S1和S2字符是否一样
public boolean isScramble(String s1, String s2) {
return helper(s1, 0, s1.length()-1, s2, 0, s2.length()-1);
}
public boolean helper(String s1,int b1,int e1,String s2,int b2,int e2)
{
//s1 == s2???
if(e1-b1 != e2-b2){return false;}
if(b1 == e1)
{
return s1.charAt(b1) == s2.charAt(b2);
}
int[] c = new int[256];
for(int i=b1;i<=e1;i++){c[s1.charAt(i)]++;}
for(int i=b2;i<=e2;i++){c[s2.charAt(i)]--;}
for(int i=b1;i<=e1;i++){if(c[s1.charAt(i)]!=0)return false;}
for(int i = 0;i<e1-b1;i++)
{
if((helper(s1, b1, b1+i, s2, b2, b2+i) && helper(s1, b1+i+1, e1, s2, b2+i+1, e2))
)
{
return true;
}
if(helper(s1, b1, b1+i, s2, e2-i, e2)&&helper(s1, b1+i+1, e1, s2, b2, b2+e1-b1-i-1)) return true;
}
return false;
}
思路2:
dp dp[i][j][len] ||= dp[i][j][k] && dp[i+k][j+k][len-k] || dp[i][j+len-k][k] && dp[i+k][j][len-k];
public class Solution {
public boolean isScramble(String s1, String s2)
{
boolean[][][] dp = new boolean[s1.length()][s2.length()][s1.length()+1];
for(int i=0;i<s1.length();i++)
{
for(int j=0;j<s1.length();j++)
{
if(s1.charAt(i) == s2.charAt(j))
{
dp[i][j][1] = true;
}
}
}
for(int len=2;len<s1.length()+1;len++)
{
for(int i=0;i<s1.length()-len+1;i++)
{
for(int j=0;j<s1.length()-len+1;j++)
{
for(int k = 1;k<len;k++)
{
dp[i][j][len] =dp[i][j][len]|| (dp[i][j][k] && dp[i+k][j+k][len-k]) || (dp[i][j+len-k][k] && dp[i+k][j][len-k]);
}
}
}
}
return dp[0][0][s1.length()];
}
}