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.
思路1:递归的方法,简单粗暴,反复比较生成的两个子串的两种情况:
1)s1左侧与s2左侧比较,s1右侧与s2右侧比较;
2)s1左侧与s2右侧比较,s1右侧与s2左侧比较。
注:比较的时候,保证字符串的长度是一样的否侧判断下去就没有意义了。
class Solution { public: bool isScramble(string s1, string s2) { int nLen=s1.size(); if(s1.compare(s2)==0) return true; string temp1(s1),temp2(s2); sort(temp1.begin(),temp1.end()); sort(temp2.begin(),temp2.end()); if(temp1.compare(temp2)!=0) return false; for(int i=1;i<nLen;i++) { string str11=s1.substr(0,i); string str12=s1.substr(i,nLen-i); string str21=s2.substr(0,i); string str22=s2.substr(i,nLen-i); if(isScramble(str11,str21)&&isScramble(str12,str22)) return true; string str23=s2.substr(0,nLen-i); string str24=s2.substr(nLen-i,i); if(isScramble(str11,str24)&&isScramble(str12,str23)) return true; } return false; } };
思路2:动态规划的思路。dp[i][j][k]表示s1从i开始k个字符和s2从j开始k个字符是否为Scramble String。
1.k==1时,dp[i][j][1]=(s1[i]==s2[j])
2.k>1时,dp[i][j][k]=(dp[i][j][index]&&dp[i+index][j+index][k-index]||dp[i][j+k-index][index]&&dp[i+index][j][k-index]),index在1~k之间。
也就是S1左==S2左 &&s1右==s2右或者s1左==s2右&&s1右==s2左。
class Solution { public: bool isScramble(string s1, string s2) { int n=s1.size(); if(s1.size()!=s2.size()) return false; vector<vector<vector<bool>>> dp(n,vector<vector<bool> >(n,vector<bool>(n+1,false))); for(int k=1;k<=n;k++) { for(int i=0;i<=n-k;i++) { for(int j=0;j<=n-k;j++) { if(k==1) dp[i][j][1]=(s1[i]==s2[j]); else { for(int index=1;index<k;index++) { if((dp[i][j][index]&&dp[i+index][j+index][k-index])||(dp[i][j+k-index][index]&&dp[i+index][j][k-index])) { dp[i][j][k]=true; break; } } } } } } return dp[0][0][n]; } };