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.
三维动态规划: f(i, j, n) = || ((f(i, j, m) && f(i + m, j + m, n - m)) || f(i, j + n - m, m) && f(i + m, j, n - m)) for 1 <= m < n
where f(i, j, n)
is true iff substring starts at s1[i] and substring starts at s2[j] both with length n are scrambled
class Solution { public: bool isScramble(string s1, string s2) { // Start typing your C/C++ solution below // DO NOT write int main() function int n = s1.size(); if (s2.size() != n) return false; if(s1 == s2 ) return true; bool f[n][n][n+1]; for(int i= 0; i< n; i++) for(int j = 0; j< n; j++) { f[i][j][0] = true;//len 0 其实没用,只是为了k 的编程容易而已 f[i][j][1] = s1[i] == s2[j] ; } for(int len = 2; len <= n; len ++) for( int i = 0; i + len -1 < n;i++) for(int j = 0; j + len -1 <n;j++) { f[i][j][len] = false; for(int k = 1; k< len ; k++){ if ( (f[i][j][k] && f[i+k][j+k][len-k]) || (f[i][j+len-k][k] && f[i+k][j][len-k]) ) { f[i][j][len] = true; break; } } } return f[0][0][n]; } };